2013-08-18 35 views
9

Próbuję mieć STDOUT/STDERR z execed proces potomny wrócić do rodzica za pośrednictwem potoku w Perl. Najbliższe, co widziałem, co chcę zrobić, to: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.htmlPrzekierowywanie stdin/stdout z procesu execed do potoku w Perlu

Poniżej znajduje się uproszczony przykład tego, co próbuję zrobić. Próbowałem również wariant powyższego linku. Nie widzę, co robię źle ...

#!/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

Możesz być zainteresowany [IPC :: Open2] (http://perldoc.perl.org/IPC/Open2.html). – squiguy

Odpowiedz

5

Nie da się przekierować deskryptorów plików tylko z zadaniami. Zamiast tego należy użyć open, jak opisano w perldoc -f open. W twoim przypadku kod dziecko będzie wyglądać następująco:

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

Slaven Rezic ma właściwą odpowiedź, dlaczego Twój kod nie działa, ale należy również pamiętać o skrót, który można wykorzystać. Specjalna rura + widelec open READER, '-|' wykonuje prawie wszystkie prace konfiguracyjne dla ciebie, tworząc proces potomny z jego pisaniem STDOUT do potoku, który rodzic może odczytać z READER. To właśnie pozostawia przekierowanie STDERR, aby zrobić to ręcznie.

skróconego kodu wygląda następująco:

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

Kod ten jest kolejnym sposobem na rurze stdout i stderr od procesu potomnego.

#!/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) ; 

}