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