saintmike has asked for the wisdom of the Perl Monks concerning the following question:
Child processes inherit their parent's file handles. So, if you want
to redirect STDOUT to a file in both the parent and the child, you can
do something like this:
This works as expected and prints to the file, not to STDOUT. You can do something similar by tie()ing the file handle to a trapper class:close STDOUT; open STDOUT, ">out" or die; my $pid = fork(); die "" if !defined $pid; exit 0 if $pid; # parent exits print "Message!\n"; #child prints to file
This works as well, printing to the file instead of STDOUT. However, if you replace the print statement by exec() to overload the child process with something else, like /bin/date, it doesn't work anymore, the child process will print to STDOUT, not to the file:tie *STDOUT, TrapClass; my $pid = fork(); die "" if !defined $pid; exit 0 if $pid; # parent exits print "Message!\n"; # child prints to file package TrapClass; sub TIEHANDLE { my $class = shift; open(my $fh, ">out") or die; bless { fh => $fh }, $class; } sub PRINT { my $self = shift; my $fh = $self->{fh}; print $fh @_; }
This is puzzling, given that exec() works just fine if you redirect the file handle the good-old fashioned way:tie *STDOUT, TrapClass; my $pid = fork(); die "" if !defined $pid; exit 0 if $pid; # parent exits exec "/bin/date"; # child prints to STDOUT!! package TrapClass; sub TIEHANDLE { my $class = shift; open(my $fh, ">out") or die; bless { fh => $fh }, $class; } sub PRINT { my $self = shift; my $fh = $self->{fh}; print $fh @_; }
Does anyone know what kind of dark magic is going on in tie() to breaks the third case?close STDOUT; open STDOUT, ">out" or die; my $pid = fork(); die "" if !defined $pid; exit 0 if $pid; # parent exits exec "/bin/date"; #child prints to file
Back to
Seekers of Perl Wisdom