2008-08-19 11 views
10

पर्ल में, आप सिस्टम() या `` (बैकटिक्स) का उपयोग कर सिस्टम कमांड निष्पादित कर सकते हैं। आप एक चर में कमांड के आउटपुट को कैप्चर भी कर सकते हैं। हालांकि, यह पृष्ठभूमि में प्रोग्राम निष्पादन को छुपाता है ताकि आपकी स्क्रिप्ट निष्पादित करने वाला व्यक्ति इसे देख न सके।पर्ल की प्रणाली() कमांड को कैसे प्रिंट कर सकती है?

आम तौर पर यह उपयोगी होता है लेकिन कभी-कभी मैं देखना चाहता हूं कि दृश्यों के पीछे क्या चल रहा है। आप इसे कैसे बनाते हैं ताकि निष्पादित आदेश टर्मिनल पर मुद्रित किए जाते हैं, और उन प्रोग्रामों के आउटपुट टर्मिनल पर मुद्रित होते हैं? यह .bat "@echo on" के बराबर होगा।

उत्तर

8

जैसा कि मैं समझता हूं, सिस्टम() आदेश के परिणाम मुद्रित करेगा, लेकिन इसे असाइन नहीं करेगा। उदाहरण के लिए।

[[email protected] /]$ perl -e '$ls = system("ls"); print "Result: $ls\n"' 
bin dev home lost+found misc net proc sbin  srv System tools var 
boot etc lib media  mnt opt root selinux sys tmp  usr 
Result: 0 

बैकटिक आदेश के आउटपुट को कैप्चर और नहीं इसे प्रिंट होगा:

[[email protected] /]$ perl -e '$ls = `ls`; print "Result: $ls\n"' 
Result: bin 
boot 
dev 
etc 
home 
lib 

आदि ...

अद्यतन: आप जा रहा है आदेश के नाम पर प्रिंट करना चाहते हैं सिस्टम() 'डी' साथ ही, मुझे लगता है कि Rudd का दृष्टिकोण अच्छा है।

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 
4

इसके बजाय खोलें का उपयोग करें। फिर आप कमांड के आउटपुट को कैप्चर कर सकते हैं।

open(LS,"|ls"); 
print LS; 
18

मैं किसी भी डिफ़ॉल्ट तरीका यह है के बारे में पता नहीं है, लेकिन आप के लिए यह करने के लिए एक सबरूटीन परिभाषित कर सकते हैं:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    system($cmd); 
} 

my $cmd = $ARGV[0]; 
execute($cmd); 

और फिर कार्रवाई में इसे देख यहाँ समेकन के लिए बार-बार :

pbook:~/foo rudd$ perl foo.pl ls 
ls 
file1 file2 foo.pl 
2

हम्म, दिलचस्प है कि लोग इस अलग-अलग तरीकों का जवाब दे रहे हैं। मुझे लगता है कि mk और Daniel Fone ने इसे आदेश के stdout को देखने/कुशलतापूर्वक देखने के लिए व्याख्या की है (न तो उनके समाधानों में से कोई भी stderr fwiw को कैप्चर करता है)। मुझे लगता है कि Rudd करीब आ गया। रुड की प्रतिक्रिया पर आप जो मोड़ बना सकते हैं वह आपके सिस्टम के साथ निर्मित सिस्टम() कमांड को ओवरवेट करना है ताकि आपको अपने निष्पादन() कमांड का उपयोग करने के लिए मौजूदा कोड को फिर से लिखना पड़े।

रुड की पोस्ट से उसके अमल() उप का उपयोग कर, आप अपने कोड के शीर्ष पर कुछ इस तरह हो सकता है:

if ($DEBUG) { 
    *{"CORE::GLOBAL::system"} = \&{"main::execute"}; 
} 

मुझे लगता है कि काम करेंगे, लेकिन मैं स्वीकार करने के लिए इस वूडू है और यह हो गया है थोड़ी देर के बाद से मैंने यह कोड लिखा था।

# importing into either the calling or global namespace _must_ be 
    # done from import(). Doing it elsewhere will not have desired results. 
    delete($opts{handle_system}); 
    if ($do_system) { 
    if ($do_system eq 'local') { 
     *{"$callpkg\::system"} = \&{"$_package\::system"}; 
    } else { 
     *{"CORE::GLOBAL::system"} = \&{"$_package\::system"}; 
    } 
    } 
+0

वैश्विक 'system' आदेश जगह के साथ बड़ी समस्या यह है कि' system' एक जटिल प्रोटोटाइप कि द्वारा दोहराया नहीं जा सकता है उपयोगकर्ता द्वारा निर्दिष्ट प्रोटोटाइप सिस्टम। नतीजतन, अगर आप अपने सिस्टम के साथ 'system' को प्रतिस्थापित करते हैं तो कुछ कोड काम नहीं करेंगे। – cjm

1

दूसरों जवाब में बताया गया साथ गठबंधन करने के लिए एक और तकनीक tee आदेश का उपयोग करने के लिए है: यहाँ कोड मैं साल पहले लिखा था एक स्थानीय (बुला नाम स्थान) पर सिस्टम कॉल अवरोधन करने या वैश्विक स्तर मॉड्यूल लोड करते समय है । उदाहरण के लिए:

open(F, "ls | tee /dev/tty |"); 
while (<F>) { 
    print length($_), "\n"; 
} 
close(F); 

यह दोनों बाहर मौजूदा निर्देशिका में फ़ाइलों (tee /dev/tty का एक परिणाम के रूप में) प्रिंट होगा और प्रत्येक फ़ाइल नाम पढ़ा की लंबाई प्रिंट आउट।

4

यहाँ एक अपडेट हो जाता है पर अमल कि परिणाम प्रिंट और उन्हें वापस आ जाएगी:

sub execute { 
    my $cmd = shift; 
    print "$cmd\n"; 
    my $ret = `$cmd`; 
    print $ret; 
    return $ret; 
} 
संबंधित मुद्दे