`Posix_spawn` का आउटपुट प्राप्त करें


9

इसलिए मैं POSIX का उपयोग करके यूनिक्स / लिनक्स में एक प्रक्रिया चला सकता हूं, लेकिन क्या कोई तरीका है जो मैं किसी फ़ाइल के लिए 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एक फाइल करते हैं ।/tmp/foo-log1
  • फिर हम posix_spawn_file_actions_adddup2fd 2(उर्फ stderr) को fd 1।
  • ध्यान दें कि अभी तक कुछ भी खोला या नकल नहीं किया गया है । पिछले दो कार्यों ने केवल इस child_fd_actionsबात पर ध्यान दिया कि इन कार्यों को लिया जाना है।
  • और अंत में हम ऑब्जेक्ट के 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कथन याद कर रहा है।
मैक्सक्लेपजिग

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फ़ंक्शन गलत तरीके से सेट नहीं होते हैं, इसके बजाय, अधिकांश अन्य UNIX फ़ंक्शन के विपरीत, वे एक त्रुटि कोड लौटाते हैं। इस प्रकार, हम उपयोग नहीं कर सकते हैं perror()लेकिन ऐसा कुछ उपयोग करना होगा strerror()

हम दो स्पॉन फ़ाइल क्रियाओं का उपयोग करते हैं: Addopen और addup2। Addopen एक सामान्य के समान है, open()लेकिन आप एक फ़ाइल डिस्क्रिप्टर भी निर्दिष्ट करते हैं, जो पहले से ही खुला होने पर स्वतः बंद हो जाता है (यहाँ 1, यानी stdout)। Addup2 के समान प्रभाव होते हैं dup2(), अर्थात टारगेट फ़ाइल डिस्क्रिप्टर (यहाँ 2, अर्थात stderr) को 1 से 2 से पहले ही बंद कर दिया जाता है। उन कार्यों को केवल उस बच्चे द्वारा ही अंजाम दिया जाता है, जो उसके द्वारा posix_spawnनिर्दिष्ट कमांड को निष्पादित करने से ठीक पहले किया जाता है।

जैसे fork(), posix_spawn()और posix_spawnp()तुरंत जनक के पास लौटना। इस प्रकार, हमें उपयोग करना है waitid()या waitpid()स्पष्ट रूप से child_pidसमाप्ति पर प्रतीक्षा करनी है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.