2008-08-19 8 views
25

आप बाहरी प्रोग्राम कैसे चलाते हैं और सी का उपयोग करके कमांड लाइन पैरामीटर पास करते हैं? यदि आपको ऑपरेटिंग सिस्टम एपीआई का उपयोग करना है, तो विंडोज, मैक और लिनक्स के लिए एक समाधान शामिल करें।सी में आप एक और प्रक्रिया कैसे फैलते हैं?

+2

मुझे लगता है कि आपको अपने प्रश्न को फिर से लिखना होगा - एक बाहरी प्रक्रिया खोलना * बिल्कुल * एक ही प्रक्रिया के समान नहीं है ... एक अंतर है। –

उत्तर

10
#include <stdlib.h> 

int main() 
{ 
    system("echo HAI"); 

    return 0; 
} 
+6

सिस्टम का कभी भी उपयोग न करें। यह मल्टीथ्रेडिंग से बहुत दूर है कि यह आपको कड़ी मेहनत करेगा और आपके जंक में होगा। उदाहरण के लिए सिग्नल हैंडलिंग गलतियों में से कुछ सबसे खराब समस्याएं हैं और "सिस्टम" इससे भरा है। – Lothar

1

एक समाधान प्रणाली समारोह stdlib.h में परिभाषित किया गया है

int system(const char *string); 

system api example

4

यूनिक्स पर, मुझे लगता है कि आप मूल रूप से यह कांटा करने के लिए अगर आप चाहते हैं पैदा की प्रक्रिया अलग चलाने की आवश्यकता आपके स्पॉइंग एक से: उदाहरण के लिए यदि आप अपनी स्पॉन्गिंग प्रक्रिया को छोड़ने पर अपनी तैयार प्रक्रिया को समाप्त नहीं करना चाहते हैं।

Here is a पृष्ठ जो फोर्क, सिस्टम, एक्ज़ेक के बीच सभी सूक्ष्म अंतर बताता है।

यदि आप विन, मैक और लिनक्स पर काम करते हैं, तो मैं आपको Qt Framework and its QProcess object की सलाह दे सकता हूं, लेकिन मुझे नहीं पता कि यह आपके लिए एक विकल्प है या नहीं।

QString program = "./yourspawnedprogram"; 
QProcess * spawnedProcess = new QProcess(parent); 
spawnedProcess->start(program); 
// or spawnedProcess->startDetached(program); 

और अतिरिक्त के लिए, तुम भी, माँ प्रक्रिया से बच्चे की प्रक्रिया को मारने और इसके साथ संचार में रख सकते हैं: महान लाभ है कि आप विंडोज लिनक्स और मैक पर एक ही कोड को संकलित करने में सक्षम हो जाएगा है एक धारा के माध्यम से।

14

यदि आप बाहरी प्रोग्राम के आउटपुट को पढ़ने जैसे अधिक जटिल परिचालन करना चाहते हैं, तो आपको popen सिस्टम कॉल द्वारा बेहतर सेवा दी जा सकती है। उदाहरण के लिए, प्रोग्राम के रूप में एक निर्देशिका सूची तक पहुँचने के लिए (यह कुछ हद तक एक मूर्ख उदाहरण है, लेकिन उपयोगी एक उदाहरण के रूप में), तो आप इस तरह कुछ लिख सकते हैं:

#include <stdio.h> 

int main() 
{ 
    int entry = 1; 
    char line[200]; 
    FILE* output = popen("/usr/bin/ls -1 /usr/man", "r"); 
    while (fgets(line, 199, output)) 
    { 
    printf("%5d: %s", entry++, line); 
    } 
} 

इस

1: cat1 
2: cat1b 
3: cat1c 
4: cat1f 
5: cat1m 
6: cat1s 
... 
तरह उत्पादन देने के लिए
15

यह वास्तव में, आप क्या करना, वास्तव में कोशिश कर रहे हैं पर निर्भर करता है क्या यह है के रूप में:

  1. ओएस निर्भर
  2. स्पष्ट नहीं है कि आप क्या करने की कोशिश कर रहे हैं।

फिर भी, मैं आपके लिए निर्णय लेने के लिए कुछ जानकारी प्रदान करने की कोशिश करूंगा।
यूनिक्स पर, fork() उस स्थान से आपकी प्रक्रिया का एक क्लोन बनाता है जहां आपने कांटा कहा था। मतलब, अगर मैं निम्नलिखित प्रक्रिया है:

#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
    printf("hi 2 u\n"); 
    int mypid = fork(); 

    if(0 == mypid) 
     printf("lol child\n"); 
    else 
     printf("lol parent\n"); 

    return(0); 
} 

आउटपुट के रूप में दिखाई देगा इस प्रकार है:

हाय 2 यू
lol बच्चे
lol माता पिता

जब आप fork() बच्चे में लौटाई गई पिड 0 है, तो माता पिता में वापस पिड बच्चे की पिड है। ध्यान दें कि "hi2u" केवल एक बार मुद्रित है ...माता-पिता द्वारा।

execve() और कार्यों के अपने परिवार लगभग हमेशा fork().execve() और पसंद के साथ उपयोग किया जाता है कि आप इसे करने के लिए पारित आवेदन के नाम के साथ वर्तमान stackframe के ऊपर लिख। execve() लगभग हमेशा fork() के साथ उपयोग किया जाता है जहां आप एक बच्चे की प्रक्रिया को फोर्क करते हैं और यदि आप माता-पिता हैं तो आप जो कुछ भी करना चाहते हैं वह करते हैं और यदि आप बच्चे हैं तो आप एक नई प्रक्रिया निष्पादित करते हैं। execve() का लगभग हमेशा waitpid() के साथ उपयोग किया जाता है - वेटपिड एक बच्चे की प्रक्रिया का एक पिड लेता है और, सचमुच तक प्रतीक्षा करता है जब तक बच्चा समाप्त नहीं हो जाता और बच्चे के बाहर निकलने की स्थिति को वापस नहीं लौटाता।

इस जानकारी का उपयोग करके, आपको एक बहुत ही बुनियादी खोल लिखने में सक्षम होना चाहिए; एक जो कमांड लाइन पर प्रक्रिया नाम लेता है और प्रक्रियाओं को चलाता है जो आप इसे बताते हैं। बेशक, गोले उस से अधिक करते हैं, जैसे कि पाइपिंग इनपुट और आउटपुट, लेकिन आप fork(), execve() और waitpid() का उपयोग कर मूल बातें पूरी करने में सक्षम होना चाहिए।

नोट: यह * निक्स विशिष्ट है! यह विंडोज पर काम नहीं करेगा।

आशा है कि इससे मदद मिलेगी।

1

यदि आपको अपने बाहरी कमांड के आउटपुट को जांच/पढ़ने/पार्स करने की आवश्यकता है, तो मैं सिस्टम() के बजाय popen() का उपयोग करने का सुझाव दूंगा।

1

विंडोज़ पर प्लेटफॉर्म-निर्भर व्यंजनों का बोलना, CreateProcess पर, पॉज़िक्स (लिनक्स, मैक) पर fork + execvp का उपयोग करें। लेकिन system() आपकी मूलभूत आवश्यकताओं को कवर करना चाहिए और मानक पुस्तकालय का हिस्सा होना चाहिए।

5

मैं सिस्टम का उपयोग न करने के लिए एक बड़ी चेतावनी देना चाहता हूं और जब आप लाइब्रेरी लिखते हैं तो 100% सिस्टम का उपयोग कभी नहीं करते हैं। यह 30 साल पहले बनाया गया था जब मल्टीथ्रेडिंग यूनिक्स नामक खिलौना ऑपरेटिंग सिस्टम के लिए अज्ञात थी। और यह अभी भी उपयोग योग्य नहीं है जब भी लगभग सभी कार्यक्रम बहुप्रचारित होते हैं।

पॉपन का उपयोग करें या फोर्क + execvp करें, अन्य सभी आपको सिग्नल हैंडलिंग, पर्यावरण हैंडलिंग कोड आदि में दुर्घटनाओं के साथ समस्याएं ढूंढने में कठिनाई होगी। यह शुद्ध बुराई और शर्म की बात है कि चयनित और सबसे अधिक मूल्यांकित उत्तर प्रचारित कर रहा है "सिस्टम" का उपयोग। कार्यस्थल पर कोकीन के उपयोग को बढ़ावा देने के लिए यह अधिक स्वस्थ है।

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