2013-08-18 7 views
9

में निष्पादित प्रक्रिया से पाइप तक stdin/stdout को रीडायरेक्ट करने के लिए मैं एक निष्पादित बाल प्रक्रिया से STDOUT/STDERR रखने की कोशिश कर रहा हूं, पेरल में एक पाइप के माध्यम से माता-पिता के पास वापस जाएं। सबसे नज़दीक मैंने देखा है कि मैं क्या करना चाहता हूं: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.htmlपर्ल

निम्नलिखित जो मैं करने की कोशिश कर रहा हूं उसका एक संक्षिप्त उदाहरण है। मैंने उपरोक्त लिंक का एक संस्करण भी आजमाया। मैं नहीं देख सकता कि मैं क्या गलत कर रहा हूं ...

#!/usr/bin/env perl 

use strict ; 
use warnings ; 

my $cmd = "/usr/bin/who -a" ; # anything to stdout 

pipe(READER, WRITER) ; 
my $child = fork() ; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    close(WRITER) ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 

    close(READER) ; 
    close(STDOUT); 
    close(STDERR); 
    *STDOUT = *WRITER ; 
    *STDERR = *WRITER ; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
} 
+2

आप [आईपीसी :: Open2] में रुचि हो सकती (http://perldoc.perl.org/IPC/Open2.html)। – squiguy

उत्तर

5

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

print "I am the child. My pid = $$\n" ; 

    close(READER) ; 

    open STDOUT, ">&", \*WRITER or die $!; 
    open STDERR, ">&", \*WRITER or die $!; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
4

स्लावेन Rezic क्यों अपने कोड काम नहीं करता है करने के लिए सही जवाब है, लेकिन आप भी एक शॉर्टकट है कि आप उपयोग कर सकते हैं के बारे में पता होना चाहिए। विशेष पाइप + कांटा open READER, '-|' आपके लिए लगभग सभी सेटअप कार्य करता है, एक STDOUT के साथ एक बच्चे की प्रक्रिया को एक पाइप में लिखता है जिसे माता-पिता READER के साथ पढ़ सकते हैं। मैन्युअल रूप से करने के लिए यह केवल STDERR पुनर्निर्देशन छोड़ देता है।

कोड का छोटा संस्करण इस तरह दिखता है:

my $child = open READER, '-|'; 
defined $child or die "pipe/fork: $!\n"; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 

    open STDERR, '>&STDOUT'; 

    print "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 
} 
0

इस कोड को STDOUT और STDERR बच्चे प्रक्रिया से पाइप के लिए एक और तरीका है।

#!/usr/bin/env perl 
use strict ; 
use warnings; 

my $cmd = "/usr/bin/who -a" ; # anything to stdout 

pipe(READER, WRITER) ; 
my $child = fork() ; 
if ($child) { 
    print "I am the parent: My pid = $$ junior = $child\n" ; 
    close(WRITER) ; 
    my @output = <READER> ; 
    print @output ; 
    print "parent is DONE\n" ; 
} else { 
    print "I am the child. My pid = $$\n" ; 
    close(READER) ; 
    open(STDERR,">&", WRITER) or die "Cannot duplicate STDERR; 
    open(STDOUT,">&", WRITER) or die "cannot duplicate STDOUT"; 

    print WRITER "XXX ouput before exec....\n" ; 

    exec($cmd) or exit(1) ; 

}