2008-12-13 19 views
22

मुझे एक पर्ल स्क्रिप्ट मिली है जिसे एक और पर्ल स्क्रिप्ट निष्पादित करने की आवश्यकता है। यह दूसरी स्क्रिप्ट सीधे कमांड लाइन पर निष्पादित की जा सकती है, लेकिन मुझे इसे अपने पहले कार्यक्रम के भीतर से निष्पादित करने की आवश्यकता है। मुझे इसे कुछ पैरामीटर पारित करने की आवश्यकता होगी जो सामान्य रूप से चलने पर पारित हो जाएंगे (पहली स्क्रिप्ट समय-समय पर चलती है, और सिस्टम शर्तों के एक निश्चित सेट के तहत दूसरी स्क्रिप्ट निष्पादित करती है)।मैं पर्ल स्क्रिप्ट के भीतर से पर्ल स्क्रिप्ट कैसे चला सकता हूं?

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

(संपादित करें:।। ओह, अब अतः कुछ संबंधित सवालों का सुझाव This one करीब है, लेकिन वास्तव में नहीं के रूप में मैं क्या पूछ रहा हूँ दूसरा कार्यक्रम की संभावना एक घंटे या अधिक ले जाएगा चलाने के लिए एक ही (मैं के बहुत सारे/ओ), तो मैं नहीं यकीन है कि एक बंद मंगलाचरण इस के लिए सही फिट है अगर आप कमांड के उत्पादन पर कब्जा करने की जरूरत है।)

उत्तर

28

आपके वर्तमान पर्ल दुभाषिया का स्थान विशेष चर $^X में पाया जा सकता है। यह महत्वपूर्ण है कि यदि आपके पथ में पर्ल नहीं है, या यदि आपके पास एकाधिक पीएलएल संस्करण उपलब्ध हैं लेकिन यह सुनिश्चित करने के लिए कि आप बोर्ड में एक ही का उपयोग कर रहे हैं।

अन्य पर्ल कार्यक्रमों सहित बाहरी आदेशों को निष्पादित करते समय, यह निर्धारित करना कि वे वास्तव में भाग गए हैं, काफी मुश्किल हो सकते हैं। निरीक्षण $? तक चलने वाले मानसिक निशान छोड़ सकते हैं, तो मैं (CPAN से उपलब्ध है) IPC::System::Simple का उपयोग करना पसंद:

use strict; 
use warnings; 
use IPC::System::Simple qw(system capture); 

# Run a command, wait until it finishes, and make sure it works. 
# Output from this program goes directly to STDOUT, and it can take input 
# from your STDIN if required. 
system($^X, "yourscript.pl", @ARGS); 

# Run a command, wait until it finishes, and make sure it works. 
# The output of this command is captured into $results. 
my $results = capture($^X, "yourscript.pl", @ARGS); 

उपरोक्त उदाहरण किसी भी तर्क आप अपने बाहरी कार्यक्रम को पारित करना चाहते हैं @ARGS में जाने के दोनों में। शैल को उपरोक्त दोनों उदाहरणों में भी टाला जाता है, जो आपको एक छोटा सा गति लाभ देता है, और शैल मेटा-वर्णों से जुड़े किसी भी अवांछित बातचीत से बचाता है। उपर्युक्त कोड भी उम्मीद करता है कि सफलता के संकेत के लिए आपके दूसरे प्रोग्राम को शून्य निकास मूल्य वापस कर दिया जाए; क्या आप एक लंबी चलने वाली प्रक्रिया है और आप अपने डेटा जबकि यह उत्पन्न किया जा रहा है की प्रक्रिया चाहते हैं

# Both of these commands allow an exit value of 0, 1 or 2 to be considered 
# a successful execution of the command. 

system([0,1,2], $^X, "yourscript.pl", @ARGS); 
# OR 
capture([0,1,2, $^X, "yourscript.pl", @ARGS); 

, फिर ': यदि यह मामला नहीं है, आप अनुमति बाहर निकलने के मूल्यों का एक अतिरिक्त पहला तर्क निर्दिष्ट कर सकते हैं शायद एक पाइप खुले, या सीपीएएन से अधिक हेवीवेट आईपीसी मॉड्यूल की आवश्यकता होगी।

यह सब कहकर, किसी भी समय आपको पर्ल से एक और पर्ल प्रोग्राम कॉल करने की आवश्यकता है, तो आप इस बात पर विचार करना चाहेंगे कि मॉड्यूल का उपयोग करना बेहतर विकल्प होगा या नहीं। एक और कार्यक्रम शुरू करने से स्टार्ट-अप लागतों के मामले में काफी कुछ ओवरहेड होते हैं, और प्रक्रियाओं के बीच डेटा को स्थानांतरित करने के लिए I/O लागत होती है। यह त्रुटि प्रबंधन की कठिनाई में भी काफी वृद्धि करता है। यदि आप अपने बाहरी प्रोग्राम को मॉड्यूल में बदल सकते हैं, तो आप पाते हैं कि यह आपके समग्र डिज़ाइन को सरल बनाता है।

शुभकामनाएँ

,

पॉल

6

उपयोग बैकटिक।

उपयोग system यदि आप आदेश के उत्पादन पर कब्जा करने की जरूरत नहीं है।

TMTOWTDI: तो अन्य तरीके भी हैं, लेकिन उन दो हैं सबसे आसान और सबसे अधिक संभावना है।

1
#!/usr/bin/perl 
use strict; 

open(OUTPUT, "date|") or die "Failed to create process: $!\n"; 

while (<OUTPUT>) 
{ 
    print; 
} 

close(OUTPUT); 

print "Process exited with value " . ($? >> 8) . "\n"; 

इस प्रक्रिया date और पाइप आउटपुट filehandle जो आप एक समय में एक लाइन संसाधित कर सकते हैं करने के लिए आदेश का उत्पादन शुरू कर देंगे। जब आदेश समाप्त हो जाता है तो आप आउटपुट फ़ाइल को बंद कर सकते हैं और प्रक्रिया के वापसी मूल्य को पुनर्प्राप्त कर सकते हैं। जो कुछ भी आप चाहते हैं उसके साथ date बदलें।

3

आप एसिंक्रोनस रूप से अपने बाहरी स्क्रिप्ट -आप बस इसे शुरू करने के लिए और यह finish- करने के लिए है, तो इंतजार नहीं करना चाहता कॉल करने के लिए की जरूरत है:

# On Unix systems, either of these will execute and just carry-on 
# You can't collect output that way 
`myscript.pl &`; 
system ('myscript.pl &');  

# On Windows systems the equivalent would be 
`start myscript.pl`; 
system ('start myscript.pl'); 

# If you just want to execute another script and terminate the current one 
exec ('myscript.pl'); 
9

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

  1. बैकटिक्स: $ retVal = `` perl somePerlScript.pl ;
  2. प्रणाली() फोन
  3. eval

eval एक स्ट्रिंग (या स्ट्रिंग की एक सूची), तो 'तार eval'ing में अन्य फ़ाइल slurping के द्वारा पूरा किया जा सकता है। एक नमूना है:

#!/usr/bin/perl 
open PERLFILE, "<somePerlScript.pl"; 
undef $/; # this allows me to slurp the file, ignoring newlines 
my $program = <PERLFILE>; 
eval $program; 

4। करें:

do 'somePerlScript.pl'

+0

यह बस का उपयोग 'कर' के लिए एक बहुत आसान और अधिक संक्षिप्त होना नहीं चाहेंगे त्रुटि शामिल नहीं है? – innaM

+0

धन्यवाद। मैंने सूची में 'डू' जोड़ा। – Colin

4

इंटरप्रोसेस संचार के लिए कई विकल्पों के लिए perlipc दस्तावेज़ीकरण देखें।

अपनी पहली स्क्रिप्ट केवल दूसरे पटकथा के लिए वातावरण सेट करता है, तो आप exec की तलाश में हो सकता है।

9

आप पहले से ही अपने प्रश्न का अच्छा जवाब है, लेकिन वहाँ हमेशा posibility देखने का एक अलग बिंदु लेने के लिए है: हो सकता है आप स्क्रिप्ट है कि आप पहले स्क्रिप्ट से चलाना चाहते हैं पुनर्रचना विचार करना चाहिए।कार्यक्षमता को एक मॉड्यूल में बदलें। पहले और दूसरी स्क्रिप्ट से मॉड्यूल का प्रयोग करें।

+0

मैंने कुछ समय पहले माना था, लेकिन इसे दो कारणों से लिखा था। सबसे पहले, दूसरा डेवलपर दूसरे कार्यक्रम पर काम कर रहा है, और दूसरा, दूसरा महीना पहले खत्म हो गया था, और इसे स्वचालित करने के लिए यह पहली स्क्रिप्ट बस सोचा गया था। अगर मैंने इसे फिर से किया, तो मैं शायद इसके बजाय मॉड्यूल करूँगा। – cbowns

23

तुम बस यह कर सकते हैं।

{ 
    local @ARGV = qw<param1 param2 param3>; 
    do '/home/buddy/myscript.pl'; 
} 

perl की दूसरी प्रति में लोड होने के ऊपरी हिस्से को रोकता है।

0

मैं संपादन को आसान बनाने के लिए बाहरी फ़ाइल में गैर-सबराउटिन को ऑफ़लोड करने के लिए ऐसा कुछ करना चाहता था। मैं वास्तव में इसे एक subroutine में बना दिया। इस तरह का लाभ यह है कि बाहरी फ़ाइल में उन "मेरे" चर मुख्य नामस्थान में घोषित किए जाते हैं। यदि आप 'करते हैं' का उपयोग करते हैं तो वे स्पष्ट रूप से मुख्य नामस्थान पर माइग्रेट नहीं करते हैं। नोट नीचे प्रस्तुति से निपटने

sub getcode($) { 
    my @list; 
    my $filename = shift; 
    open (INFILE, "< $filename"); 
    @list = <INFILE>; 
    close (INFILE); 
    return \@list; 
} 

# and to use it: 

my $codelist = []; 
$codelist = getcode('sourcefile.pl'); 
eval join ("", @$codelist); 
संबंधित मुद्दे