Reputation: 1904
I need to call an external logging process from a Perl script that takes data passed to it and writes it to a network service. That is easy enough to do. However, I have the additional requirement that any writes to STDERR from the parent process gets redirected to the external process.
What I've tried do is open a file handle to a write pipe of the external process, then redirect STDERR to the file handle. Here is my test script, that unfortunately does not work yet.
#!/usr/bin/perl
use strict;
use warnings;
# open write filehandle to external process
open my $fh, '|-', 'pipefile_http',
or die "Couldn't open logfile: $!\n";
# redirect STDERR from parent process to same write filehandle to child process
my $fileno = fileno($fh);
open STDERR, ">&$fileno" or die "Couldn't switch STDERR to fileno $fileno: $!\n";
print $fh "1. print to file handle\n";
print STDERR "2. print to STDERR\n";
print "3. print to STDOUT\n";
close $fh;
exit 0;
When I run this script, it successfully redirects the print call to STDERR to the external logging process, but the print call to $fh does not work (the message disappears). Also, the script hangs indefinitely after it successfully prints message #3 to STDOUT. When I run the script with strace, I can see that the script is hanging on a waitpid() call (the pid of the external process).
Any advice on how I can do this?
Upvotes: 4
Views: 481
Reputation: 479
Just reassign STDERR
:
#!/usr/bin/perl
use strict;
use warnings;
# open write filehandle to external process
open my $fh, '|-', 'pipefile_http',
or die "Couldn't open logfile: $!\n";
# reassign STDERR
*STDERR = $fh;
print $fh "1. print to file handle\n";
print STDERR "2. print to STDERR\n";
print "3. print to STDOUT\n";
close $fh;
exit 0;
Upvotes: 3