`Posix_spawn` এর আউটপুট পান`


9

সুতরাং আমি ইউনিক্স / লিনাক্সে পসিক্স ব্যবহার করে একটি প্রক্রিয়া চালাতে পারি, তবে কি কোনও উপায় আছে যে আমি কোনও ফাইলটিতে প্রক্রিয়াটির STDOUT এবং STDERR উভয়ই সংরক্ষণ / পুনঃনির্দেশ করতে পারি? spawn.hহেডার একটি মন্দন এর রয়েছে posix_spawn_file_actions_adddup2যা প্রাসঙ্গিক দেখায়, কিন্তু আমি নিশ্চিত বেশ এটি কিভাবে ব্যবহার করতে নই।

প্রক্রিয়া স্প্যান:

posix_spawn(&processID, (char *)"myprocess", NULL, NULL, args, environ);

আউটপুট স্টোরেজ:

...?


1
এর তৃতীয় প্যারামিটারটি posix_spwanটাইপের একটি পয়েন্টার posix_spawn_file_actions_t(আপনি যেমন দিয়েছেন NULL)। অবজেক্টের posix_spawnদ্বারা নির্দিষ্ট করা হিসাবে কলিং প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে প্রাপ্ত ফাইল বিবরণকারীগুলি খুলতে, বন্ধ বা সদৃশ করবে posix_spawn_file_actions_tposix_spawn_file_actions_{addclose,adddup2}ফাংশন ইঙ্গিত কি যা FD ঘটবে ব্যবহার করা হয়।
মুড়ু

@ মুরু - আপনার কি মনে হয় আপনি একটি কাজের উদাহরণ যুক্ত করতে পারেন? আমি বুঝতে পেরেছি যে একটি "ফাইল অ্যাকশন" দ্বারা ফাংশনগুলির মধ্যে ইন্টারঅ্যাকশন করা হয়েছে তবে এটি ঠিক কীভাবে একসাথে ফিট হয়, বা যেখানে এফডি অবস্থানটি সংজ্ঞায়িত করা হয়েছে তা পরিষ্কার নয়।
nbubis

উত্তর:


16

এখানে তৈরি হওয়া প্রক্রিয়াটির ফাইল বর্ণনাকারীদের সংশোধন করার ন্যূনতম উদাহরণ এখানে দেওয়া হয়েছে foo.c:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <spawn.h>

int main(int argc, char* argv[], char *env[])
{
    int ret;
    pid_t child_pid;
    posix_spawn_file_actions_t child_fd_actions;
    if (ret = posix_spawn_file_actions_init (&child_fd_actions))
        perror ("posix_spawn_file_actions_init"), exit(ret);
    if (ret = posix_spawn_file_actions_addopen (&child_fd_actions, 1, "/tmp/foo-log", 
            O_WRONLY | O_CREAT | O_TRUNC, 0644))
        perror ("posix_spawn_file_actions_addopen"), exit(ret);
    if (ret = posix_spawn_file_actions_adddup2 (&child_fd_actions, 1, 2))
        perror ("posix_spawn_file_actions_adddup2"), exit(ret);

    if (ret = posix_spawnp (&child_pid, "date", &child_fd_actions, NULL, argv, env))
        perror ("posix_spawn"), exit(ret);
}

এটার কাজ কি?

  • এর তৃতীয় প্যারামিটারটি posix_spwanটাইপের একটি পয়েন্টার posix_spawn_file_actions_t(আপনি যেমন দিয়েছেন NULL)। অবজেক্টের posix_spawnদ্বারা নির্দিষ্ট করা হিসাবে কলিং প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে প্রাপ্ত ফাইল বিবরণকারীগুলি খুলতে, বন্ধ বা সদৃশ করবে posix_spawn_file_actions_t
  • সুতরাং আমরা একটি posix_spawn_file_actions_tঅবজেক্ট ( chiild_fd_actions) দিয়ে শুরু করব এবং এটি দিয়ে আরম্ভ করব posix_spawn_file_actions_init()
  • এখন, posix_spawn_file_actions_{addopen,addclose,addup2}ফাংশন, খোলা বন্ধ বা ডুপ্লিকেট ফাইল বর্ণনাকারী ব্যবহার করা যেতে পারে (পরে open(3), close(3)এবং dup2(3)যথাক্রমে ফাংশন)।
  • সুতরাং আমরা বিবরণী posix_spawn_file_actions_addopenফাইল করতে একটি ফাইল (ওরফে stdout)।/tmp/foo-log1
  • তারপরে আমরা posix_spawn_file_actions_adddup2fd 2(ওরফে stderr) এফডি 1।
  • মনে রাখবেন যে কিছুই এখনও খোলা বা মূর্খ হয়নি । শেষ দুটি ফাংশনটি কেবল এই child_fd_actionsপদক্ষেপটি পরিবর্তন করে তা নোট করে রাখে changed
  • এবং অবশেষে আমরা অবজেক্টের posix_spawnসাথে ব্যবহার করি child_fd_actions

এটি পরীক্ষা করে দেখুন:

$ make foo
cc     foo.c   -o foo
$ ./foo
$ cat /tmp/foo-log 
Sun Jan  3 03:48:17 IST 2016
$ ./foo +'%F %R'  
$ cat /tmp/foo-log
2016-01-03 03:48
$  ./foo -d 'foo'  
$ cat /tmp/foo-log
./foo: invalid date foo

আপনি দেখতে পাচ্ছেন যে, প্রসারিত প্রক্রিয়াটির stdout এবং stderr উভয় গিয়েছিল /tmp/foo-log


নোট করুন যে posix_spawn*ত্রুটি স্থাপন করবেন না। সুতরাং, আপনি ব্যবহার করতে পারবেন না perror()fprintf(stderr, "...: %s\n", strerror(ret))পরিবর্তে কিছু ব্যবহার করুন । এছাড়াও, মূল কাজটি একটি return 0বিবৃতি অনুপস্থিত ।
maxschlepzig

1

হ্যা, তুমি পারো. পোস্টিক্স স্প্যান ফাইলের ক্রিয়াগুলির সঠিক তালিকাটি নির্ধারণ করা অবশ্যই যাওয়ার উপায়।

উদাহরণ:

#include <errno.h>
#include <fcntl.h>
#include <spawn.h>
#include <stdio.h>
#include <string.h>    
#define CHECK_ERROR(R, MSG) do { if (R) { fprintf(stderr, "%s: %s\n",
        (MSG), strerror(R)); return 1; } } while (0)    
extern char **environ;   
int main(int argc, char **argv)
{
    if (argc < 3) {
        fprintf(stderr, "Call: %s OUTFILE COMMAND [ARG]...\n", argv[0]);
        return 2;
    }
    const char *out_filename = argv[1];
    char **child_argv = argv+2;
    posix_spawn_file_actions_t as;
    int r = posix_spawn_file_actions_init(&as);
    CHECK_ERROR(r, "actions init");
    r = posix_spawn_file_actions_addopen(&as, 1, out_filename,
            O_CREAT | O_TRUNC | O_WRONLY, 0644);
    CHECK_ERROR(r, "addopen");
    r = posix_spawn_file_actions_adddup2(&as, 1, 2);
    CHECK_ERROR(r, "adddup2");
    pid_t child_pid;
    r = posix_spawnp(&child_pid, child_argv[0], &as, NULL,
            child_argv, environ);
    CHECK_ERROR(r, "spawnp");
    r = posix_spawn_file_actions_destroy(&as);
    CHECK_ERROR(r, "actions destroy");
    return 0;
}

সংকলন এবং পরীক্ষা:

$ cc -Wall -g -o spawnp spawnp.c
$ ./spawnp log date -I
$ cat log
2018-11-03
$ ./a.out log dat 
spawnp: No such file or directory

নোট করুন যে posix_spawnফাংশনগুলি ভুল নির্ধারণ করে না, পরিবর্তে, অন্যান্য ইউনিক্স ফাংশনগুলির বিপরীতে, তারা একটি ত্রুটি কোড দেয়। সুতরাং, আমরা ব্যবহার করতে পারি না perror()তবে এর মতো কিছু ব্যবহার করতে হবে strerror()

আমরা দুটি স্প্যান ফাইল ক্রিয়া ব্যবহার করি: অ্যাডোপেন এবং অ্যাডআপ 2। অ্যাডোপেনটি একটি সাধারণের অনুরূপ open()তবে আপনি কোনও ফাইল বর্ণনাকারী নির্দিষ্ট করে যা ইতিমধ্যে খোলা থাকলে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় (এখানে 1, মানে স্টাডআউট)। অ্যাডআপ 2 এর অনুরূপ প্রভাব রয়েছে dup2(), যেমন লক্ষ্য ফাইল বর্ণনাকারী (এখানে 2, অর্থাৎ স্ট্যাডার) 1 টি 2 টি নকল হওয়ার আগেই পরমাণুভাবে বন্ধ হয়ে যায় Those এই ক্রিয়াগুলি কেবলমাত্র নির্মিত posix_spawnকমান্ডের দ্বারা নির্ধারিত কমান্ডটি কার্যকর করার আগে ডেকে তৈরি করা হয় in

ভালো লেগেছে fork(), posix_spawn()এবং posix_spawnp()অবিলম্বে পিতা বা মাতা ফিরে যান। সুতরাং, আমাদের ব্যবহার করতে হবে waitid()বা waitpid()স্পষ্টতই child_pidএর সমাপ্তির অপেক্ষায় থাকতে হবে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.