2011-04-10 14 views
7

मैं अपने सी प्रोग्राम में एक शेल कमांड चलाने के लिए चाहता हूं। लेकिन बात यह है कि मैं अपना प्रोग्राम कमांड तक इंतजार नहीं करना चाहता हूं। शेल कमांड के आउटपुट को पढ़ने की जरूरत नहीं है (यह वैसे भी कोई डेटा नहीं लौटाता है) तो मूल रूप से, क्या यह संभव है? fork का उपयोग एक नई प्रक्रिया बनाने के लिए और, बच्चे की प्रक्रिया में, exec का उपयोग अपने आदेश के साथ खोल शुरू करने के लिए:एक प्रोग्राम में एक शेल कमांड चलाना

+1

बीटीडब्ल्यू, इससे कोई फर्क नहीं पड़ता कि आप शेल कमांड या कुछ अन्य निष्पादन योग्य चलाने के लिए चाहते हैं। चाहे आप 'सिस्टम() 'या' कांटा()/exec()' दृष्टिकोण का उपयोग करें, जो कुछ आवश्यक है वह निष्पादन योग्य है। हो सकता है कि आप तदनुसार अपने प्रश्न का शीर्षक संपादित करना चाहते हैं? – Jens

उत्तर

5

fork() और system() क्या आप

+0

संभवतः exec() या इसके रूपों के साथ, शायद। – PhD

+1

'सिस्टम' में शैल कमांड के लिए बाल प्रक्रिया की प्रतीक्षा होगी - 'exec' बाल प्रक्रिया को खोल के साथ बदल देगा .. – rlc

+0

@Ronald: no। यह बच्चे की प्रक्रिया को दूसरी प्रक्रिया के साथ बदल देता है। ओपी से यह स्पष्ट नहीं है कि वह एक और प्रोग्राम या शेल कमांड लाइन चलाने के लिए चाहता है, लेकिन अगर यह बाद वाला है, तो केवल सिस्टम() चाल करेगा। exec में खोल शामिल नहीं है। –

5

ज़रूर की जरूरत है, सिर्फ fork और exec है। execv उन तर्कों को लेता है जिन्हें आप आम तौर पर खोल में देते हैं।

आपका कोड ऐसा दिखाई दे सकता:

pid_t child_pid = fork(); 
if (child_pid == 0) 
{ // in child 
    /* set up arguments */ 
    // launch here 
    execv("/bin/sh", args); 
    // if you ever get here, there's been an error - handle it 
} 
else if (child_pid < 0) 
{ // handle error 
} 

बच्चे प्रक्रिया एक SIGCHLD संकेत भेज देंगे जब यह मर जाता है। इस तरह

static void 
handle_sigchld(int signum, siginfo_t *sinfo, void *unused) 
{ 
    int status; 

    /* 
    * Obtain status information for the child which 
    * caused the SIGCHLD signal and write its exit code 
    * to stdout. 
    */ 
    if (sinfo->si_code != CLD_EXITED) 
    { 
     static char msg[] = "wrong si_code\n"; 
     write(2, msg, sizeof msg - 1); 
    } 
    else if (waitpid(sinfo->si_pid, &status, 0) == -1) 
    { 
     static char msg[] = "waitpid() failed\n"; 
     write(2, msg, sizeof msg - 1); 
    } 
    else if (!WIFEXITED(status)) 
    { 
     static char msg[] = "WIFEXITED was false\n"; 
     write(2, msg, sizeof msg - 1); 
    } 
    else 
    { 
     int code = WEXITSTATUS(status); 
     char buf[2]; 
     buf[0] = '0' + code; 
     buf[1] = '\n'; 
     write(1, buf, 2); 
    } 
} 
+0

exec में खोल शामिल नहीं है। मान लीजिए ओपी 'एलएस' चलाने के लिए चाहता है grep -v हैलो'। यह सिस्टम के साथ काम करेगा, लेकिन निष्पादन के साथ काम नहीं करेगा। –

+0

ओपी उन्हें खोलने के लिए पास कर सकता है - सिस्टम एक ही चीज करता है (लेकिन दृश्यों के पीछे एक और 'कांटा' और 'exec' करता है)। – rlc

1

प्रयास करें कोड:: यह है कि संभाल लेंगे कोड POSIX मानक (SUSv4) से उद्धृत

#include <stdlib.h> 
#include <unistd.h> 
int main(int argc, char ** argv) 
{ 
    if (!fork()) 
    { 
     execv("ls", {"myDir"}); /* Your command with arguments instead of ls. */ 
    } 
} 
+2

यह मुझे बहुत तेज़ और गंदे के रूप में मारता है क्योंकि यह मुख्य निकास तक बाहर निकलने के समय से ज़ोंबी प्रक्रिया तैयार करेगा। एक अच्छी तरह से व्यवहार किया यूनिक्स कार्यक्रम इससे बचना चाहता है। अन्य उत्तर देखें जो 'waitpid' का उपयोग करते हैं। – Jens

+0

क्षमा करें। मैं वास्तव में * nix एपीआई के साथ अच्छा नहीं हूँ :)। – JackMc

1

बस system ("command &") साथ आदेश amping बारे में क्या?

संबंधित मुद्दे