I am trying to assign STDOUT
of a forked process to a pipe. For example
use warnings;
use strict;
use feature qw(say);
use IO::Select;
my $cmd='sleep 2; echo Hello';
pipe(PREAD, PWRITE);
my $pid=fork();
if ($pid==0) {
*STDOUT=*PWRITE;
exec $cmd;
die "Could not run command \"$cmd\"";
}
my $sel = IO::Select->new( \*PREAD );
say "Waiting for background process..";
while (1) {
my @ready = $sel->can_read;
last if (! @ready);
for my $fh (@ready) {
say "Processing file descriptor ".($fh->fileno());
my $line=<$fh>;
if (! defined $line) {
say "EOF";
$sel->remove($fh);
next;
}
chomp($line);
say "Got line: \"$line\"..";
}
}
waitpid ($pid,0);
say "Done.";
But nothing appears in the pipe PREAD
; the child still outputs to STDOUT
and not to the pipe.
*STDOUT=*PWRITE;
this will only assign the perl filehandle PWRITE to the perl filehandle STDOUT, but not change the underlying file descriptor of the OS. To do this you would need to duplicate the underlying file descriptor from PWRITE to fd 1 (STDOUT):
open(STDOUT,">&PWRITE");
After you've do this PWRITE is duplicated and is now accessible as PWRITE and STDOUT. A good style is to close(PWRITE)
then to make STDOUT the only file handle for writing into the pipe.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments