Sam Choukri
Sam Choukri

Reputation: 1904

Redirect STDERR of parent process to file handle of child process

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

Answers (1)

emazep
emazep

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

Related Questions