perl redirect exec pipe stdout

redireccionando stdin/stdout desde el proceso ejecutado a la tubería en Perl



redirect exec (3)

Estoy intentando que STDOUT / STDERR de un proceso secundario ejecutado vuelva al padre a través de un conducto en Perl. Lo más parecido que he visto a lo que quiero hacer es en: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.html

El siguiente es un ejemplo simplificado de lo que estoy tratando de hacer. También probé una variante del enlace de arriba. No puedo ver lo que estoy haciendo mal ...

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


No es posible redirigir los descriptores de archivos solo con asignaciones. Más bien, uno necesita usar open como se describe en perldoc -f open . En su caso, el código hijo se vería así:

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) ;


Slaven Rezic tiene la respuesta correcta a por qué tu código no funciona, pero también debes tener en cuenta un atajo que puedes usar. El tubo + tenedor especial open READER, ''-|'' hace que casi toda la configuración funcione para usted, creando un proceso secundario con su escritura STDOUT en un conducto que el padre puede leer con el READER . Eso solo deja la redirección STDERR para que lo haga manualmente.

La versión abreviada del código se ve así:

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) ; }


Este código es otra forma de canalizar STDOUT y STDERR desde el proceso hijo.

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

}