पर्ल के बैकटिक्स, सिस्टम और एक्ज़ीक्यूशन में क्या अंतर है?


237

क्या कोई मेरी सहायता कर सकता है? पर्ल में, क्या अंतर है:

exec "command";

तथा

system("command");

तथा

print `command`;

क्या शेल कमांड चलाने के अन्य तरीके भी हैं?


8
लगभग एक सटीक की नकल stackoverflow.com/questions/797127/... , सिवाय इस एक कार्यकारी है और अन्य एक पाइप है।
माइकल मायर्स

जवाबों:


268

कार्यकारी

एक कमांड निष्पादित करता है और कभी नहीं लौटता है । यह returnएक समारोह में एक बयान की तरह है ।

यदि आदेश नहीं execमिलता है तो गलत है। यह कभी भी सही नहीं होता है, क्योंकि यदि आदेश मिलता है तो यह कभी नहीं लौटता है। वहाँ भी लौटने का कोई मतलब नहीं है STDOUT, STDERRया आदेश के निकास स्थिति। आप इसके बारे में प्रलेखन पा सकते हैं perlfunc, क्योंकि यह एक कार्य है।

प्रणाली

एक कमांड निष्पादित करता है और कमांड समाप्त होने के बाद आपकी पर्ल स्क्रिप्ट जारी रहती है।

वापसी मान कमांड का निकास स्थिति है। आप इसके बारे में प्रलेखन पा सकते हैं perlfunc

बैकटिक

जैसे systemकोई कमांड निष्पादित करता है और कमांड समाप्त होने के बाद आपकी पर्ल स्क्रिप्ट जारी रहती है।

systemवापसी मूल्य के विपरीत STDOUTकमांड का है। qx//backticks के बराबर है। आप इसके बारे में प्रलेखन पा सकते हैं perlop, क्योंकि इसके विपरीत systemऔर execयह एक ऑपरेटर है।


दूसरा तरीका

ऊपर से जो चीज गायब है, वह एसिंक्रोनस रूप से कमांड को निष्पादित करने का एक तरीका है। इसका मतलब है कि आपकी पर्ल स्क्रिप्ट और आपकी कमांड एक साथ चलती है। इससे पूरा किया जा सकता है open। यह आपको आपकी कमांड को पढ़ने STDOUT/ STDERRलिखने की अनुमति देता है STDIN। हालांकि यह प्लेटफॉर्म पर निर्भर है।

कई मॉड्यूल भी हैं जो इस कार्य को आसान कर सकते हैं। नहीं है IPC::Open2और IPC::Open3और IPC::Runसाथ ही साथ, Win32::Process::Createअगर आप खिड़कियों पर कर रहे हैं।


1
मुझे लगता है कि आप मतलब है / perlcunc / perlfunc / ... भी perlipc प्रलेखन पाइप खोलने के बारे में बहुत गहराई में चला जाता है।
एपेमिएंट

7
perlcunc, शायद यह मेरा नया निक नाम होगा ;-)
लुडविग वेन्ज़िएर्ल

8
रिकॉर्ड के लिए, backticks और qx [] भी $ आबाद करते हैं? (OS वापसी मान)।
जॉन्ज

167

सामान्य मैं प्रयोग में system, open, IPC::Open2, या IPC::Open3मुझे क्या करना चाहते हैं पर निर्भर करता है। qx//ऑपरेटर है, जबकि सरल, भी अपनी कार्यक्षमता में बाधित है त्वरित हैक्स के बहुत उपयोगी बाहर किया जाना है। मुझे openबहुत हाथ लगता है।

system: एक कमांड चलाएं और उसके लौटने का इंतजार करें

का प्रयोग करें systemजब आप एक आदेश चलाना चाहते हैं, इसके उत्पादन के बारे में परवाह नहीं है, और पर्ल स्क्रिप्ट आदेश खत्म होने तक कुछ भी करने को नहीं करना चाहती।

#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");

या

#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");

qx//या `` : एक कमांड चलाएं और इसके STDOUT पर कब्जा करें

qx//जब आप कमांड चलाना चाहते हैं, तो इसका उपयोग करें , जो STDOUT को लिखता है उसे कैप्चर करें, और कमांड खत्म होने तक पर्ल स्क्रिप्ट को कुछ भी करने के लिए नहीं चाहिए।

#arguments are always processed by the shell

#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;

#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;

exec: वर्तमान प्रक्रिया को दूसरी प्रक्रिया से बदलें।

का प्रयोग करें execके साथ forkजब आप एक आदेश चलाना चाहते हैं, इसके उत्पादन के बारे में परवाह नहीं है, और यह वापस जाने के लिए के लिए इंतजार नहीं करना चाहते हैं। systemवास्तव में बस है

sub my_system {
    die "could not fork\n" unless defined(my $pid = fork);
    return waitpid $pid, 0 if $pid; #parent waits for child
    exec @_; #replace child with new process
}

आप मैनुअल waitpidऔर perlipcमैनुअल पढ़ना भी चाह सकते हैं ।

open: एक प्रक्रिया चलाते हैं और उसके STDIN या STDERR में एक पाइप बनाते हैं

का प्रयोग करें openआप एक प्रक्रिया के STDIN के लिए डेटा लिखने या एक प्रक्रिया के STDOUT से डेटा पढ़ने की (लेकिन एक ही समय में दोनों नहीं) चाहते हैं।

#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
    or die "could not open $filename: $!";

#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
    or die "could not open $filename: $!";

IPC :: Open2 : एक प्रक्रिया चलाते हैं और STDIN और STDOUT दोनों के लिए एक पाइप बनाते हैं

IPC::Open2जब आपको किसी प्रक्रिया के STDIN और STDOUT से पढ़ना और लिखना हो तो उपयोग करें ।

use IPC::Open2;

open2 my $out, my $in, "/usr/bin/bc"
    or die "could not run bc";

print $in "5+6\n";

my $answer = <$out>;

IPC :: Open3 : एक प्रक्रिया चलाते हैं और STDIN, STDOUT और STDERR को एक पाइप बनाते हैं

IPC::Open3जब आपको प्रक्रिया के सभी तीन मानक फ़ाइल हैंडल को कैप्चर करने की आवश्यकता हो तब उपयोग करें । मैं एक उदाहरण लिखूंगा, लेकिन यह ज्यादातर उसी तरह से काम करता है जैसे IPC :: Open2 करता है, लेकिन तर्कों के लिए थोड़ा अलग क्रम और एक तीसरी फ़ाइल संभाल के साथ।


बहुत जानकारीपूर्ण और तारीख तक जवाब। धन्यवाद @ चास-ओवेन्स
जस्सी

IPC :: Open3 अधिकांश उपयोगों के लिए बहुत निम्न-स्तर है। IPC :: Run3 और IPC :: रन आमतौर पर कहीं अधिक उपयुक्त होते हैं।
इकेगामी

17

मुझे पहले मैनुअल उद्धृत करें:

परलोक निष्पादन () :

निष्पादन फ़ंक्शन एक सिस्टम कमांड निष्पादित करता है और कभी नहीं लौटाता है - यदि आप इसे वापस करना चाहते हैं तो निष्पादन के बजाय सिस्टम का उपयोग करें

perldoc प्रणाली () :

क्या वास्तव में LIST को निष्पादित करने के समान है, सिवाय इसके कि एक कांटा पहले किया जाता है , और मूल प्रक्रिया बच्चे की प्रक्रिया को पूरा करने के लिए इंतजार करती है।

निष्पादित और सिस्टम के विपरीत , बैकटिक्स आपको रिटर्न वैल्यू नहीं बल्कि एकत्रित STDOUT देता है।

perldoc `स्ट्रिंग` :

एक स्ट्रिंग जो (संभवतः) प्रक्षेपित है और फिर एक सिस्टम कमांड के रूप में / बिन / श या इसके समकक्ष के साथ निष्पादित की जाती है । शेल वाइल्डकार्ड, पाइप और पुनर्निर्देशन को सम्मानित किया जाएगा। कमांड का एकत्रित मानक आउटपुट वापस आ गया है ; मानक त्रुटि अप्रभावित है।


विकल्प:

अधिक जटिल परिदृश्यों में, जहाँ आप STDOUT, STDERR या रिटर्न कोड लाना चाहते हैं, आप IPC :: Open2 और IPC :: Open3 जैसे प्रसिद्ध मानक मॉड्यूल का उपयोग कर सकते हैं ।

उदाहरण:

use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

अंत में, IPC :: CPAN से भागो भी देखने लायक है ...


3
यह एक असभ्य प्रतिक्रिया है। आपको क्रोध के बिना मददगार बनने की कोशिश करनी चाहिए।
शेन सी। मेसन

1
मुझे लगता है कि वह सिर्फ ol 'RTFM: P
v3 का

वास्तव में असभ्य का मतलब नहीं था;) हालांकि किसी भी गलतफहमी से बचने के लिए एफ-शब्द हटा दिया गया ...
बेनेडिकट वाल्डवोगेल

2
मैंने निश्चित रूप से इसे असभ्य नहीं बताया। ब्रूस, हो सकता है, लेकिन यह एक अति-बुद्धिमान प्रश्न नहीं है, जिसके लिए एक विचारशील उत्तर की आवश्यकता होती है।
एपेमिएंट

11

पर्ल के बैकटिक्स ( `) system, और के बीच क्या अंतर है exec?

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;

exec

execएक कमांड निष्पादित करता है और पर्ल स्क्रिप्ट को फिर से शुरू नहीं करता है। यह एक स्क्रिप्ट की तरह है जैसे कि एक returnस्टेटमेंट एक फंक्शन के लिए होता है।

यदि आदेश नहीं मिला है, तो execगलत है। यह कभी भी सही नहीं होता है, क्योंकि यदि आदेश मिलता है, तो यह कभी नहीं लौटता है। वहाँ भी लौटने का कोई मतलब नहीं है STDOUT, STDERRया आदेश के निकास स्थिति। आप इसके बारे में प्रलेखन perlfunc में पा सकते हैं , क्योंकि यह एक फ़ंक्शन है।

उदाहरण के लिए:

#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";

उपरोक्त कोड में, तीन printकथन हैं, लेकिन execस्क्रिप्ट छोड़ने के कारण , केवल पहले प्रिंट स्टेटमेंट को निष्पादित किया जाता है। साथ ही, execकमांड आउटपुट को किसी भी वैरिएबल को नहीं सौंपा जा रहा है।

यहां, केवल आप केवल पहले printस्टेटमेंट का आउटपुट प्राप्त कर रहे हैं और lsमानक आउट पर कमांड निष्पादित कर रहे हैं।

system

systemएक कमांड निष्पादित करता है और कमांड समाप्त होने के बाद आपकी पर्ल स्क्रिप्ट फिर से शुरू हो जाती है। वापसी मान कमांड का निकास स्थिति है। आप इसके बारे में प्रलेखन perlfunc में पा सकते हैं ।

उदाहरण के लिए:

#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";

उपरोक्त कोड में, तीन printकथन हैं। जैसे ही स्क्रिप्ट को systemकमांड के बाद फिर से शुरू किया जाता है , तीनों प्रिंट स्टेटमेंट निष्पादित हो जाते हैं।

इसके अलावा, चलाने system का परिणाम सौंपा गया है data2, लेकिन निर्धारित मूल्य 0(से बाहर निकलने का कोड ls) है।

यहाँ, आपको पहले printस्टेटमेंट का आउटपुट मिल रहा है , फिर lsकमांड का, उसके बाद printस्टैंडर्ड आउट पर अंतिम दो स्टेटमेंट के आउटपुट ।

बैकटिक्स ( `)

जैसे system, backticks में कमांड को एनक्लोज करना उस कमांड को निष्पादित करता है और कमांड समाप्त होने के बाद आपकी पर्ल स्क्रिप्ट फिर से शुरू हो जाती है। इसके विपरीत system, वापसी मान STDOUTकमांड का है। qx//backticks के बराबर है। आप इसके बारे में प्रलेखन perlop में पा सकते हैं , क्योंकि सिस्टम के विपरीत और exec, यह एक ऑपरेटर है।

उदाहरण के लिए:

#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";

उपरोक्त कोड में, तीन printकथन हैं और तीनों को निष्पादित किया जा रहा है। का आउटपुट lsसीधे बाहर मानक पर नहीं जा रहा है, लेकिन चर को सौंपा गया है data2और फिर अंतिम प्रिंट स्टेटमेंट द्वारा मुद्रित किया गया है।


उदाहरण के साथ सबसे अच्छा स्पष्टीकरण। बहुत बहुत धन्यवाद।
अर्सलन अनवर

2

'एक्ज़िक' और 'सिस्टम' के बीच का अंतर यह है कि एक्ज़क्यूट आपके वर्तमान प्रोग्राम को 'कमांड' से बदल देता है और आपके प्रोग्राम पर वापस नहीं लौटता। दूसरी ओर, सिस्टम 'कमांड' को फोर्क्स और रन करता है और रनिंग होने पर आपको 'कमांड' की एग्जिट स्थिति देता है। पिछला टिक 'कमांड' चलाता है और फिर एक स्ट्रिंग देता है जो अपने मानक आउट का प्रतिनिधित्व करता है (जो भी स्क्रीन पर मुद्रित होता है)

आप शेल कमांड चलाने के लिए पोपेन का उपयोग भी कर सकते हैं और मुझे लगता है कि एक शेल मॉड्यूल है - 'शेल का उपयोग करें' जो आपको विशिष्ट शेल कमांड के लिए पारदर्शी पहुंच प्रदान करता है।

आशा है कि यह आपके लिए स्पष्ट करता है।


शायद आपका मतलब है use Shell;( search.cpan.org/dist/Shell/Shell.pm )? यह व्यापक रूप से स्थापित किया गया है, न ही यह सवाल करने के लिए लागू हो, मुझे लगता है कि है ...
ephemient

1
उनके प्रश्न का अंतिम भाग "शेल कमांड चलाने के अन्य तरीके हैं" - शेल शेल कमांड चलाने का एक और तरीका है।
शेन सी। मेसन

2
डॉक्स विशेष रूप से बताता है "यह पैकेज एक शो केस के रूप में शामिल है, जिसमें कुछ पर्ल फीचर्स को दर्शाया गया है। यह उत्पादन कार्यक्रमों के लिए नहीं होना चाहिए। हालांकि यह मनमाना कमांड के मानक आउटपुट प्राप्त करने के लिए एक सरल इंटरफ़ेस प्रदान करता है, बेहतर हो सकता है। आपको जो चाहिए वो हासिल करने के तरीके। ”
चास। २ Ow

2
फिर से, इसने उनके प्रश्न का उत्तर दिया 'अन्य तरीके हैं'
शेन सी। मेसन

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