smithgw has asked for the wisdom of the Perl Monks concerning the following question:

All -- I know there are some similar posts, but I am not sure if I need to re-engineer my code. I have a forking queue that will spawn a child backup process, and log everything to a file. The only problem is that I am loosing stderr. Is there an easy way to do this without reworking my code:
sub fork_backup { my $lpar = shift; if ( ( scalar keys %children ) < $max_children ) { my $pid = (open($lpar,"-|")); if ( $pid ) { # this is parent process $children{$pid} = $lpar; print "Child Backup [$pid][".$children{$pid}."] started a +t ".localtime()."\n"; print MAINLOG "\nChild Backup [$pid][".$children{$pid}."] + started at ".localtime( )."\n"; $processing_time{$pid} = time(); open(HOSTLOG,">>./$main_log_dir/$lpar.out"); print HOSTLOG "\nChild Backup [$pid][".$children{$pid}."] + started at ".localtime( )."\n"; close(HOSTLOG); } else { if ( not defined $pid ) { die "\n\nWoah: Failed to fork a child!\n"; } # this is child process # This is where the meat goes! my $backup_command; if ( ($lpar_oslevel{$lpar}) eq "5.3" || ($lpar_oslevel{$lp +ar}) eq "6.1" ) { $sysbackcmd="blah"; print "Sysback Com +mand - 5.3: $sysbackcmd\n"; #Put the real sysback command in here later (for 5.3) exec("ssh -q -o ConnectTimeOut=5 $lpar \"$sysbackcmd\" +"); #Put the real sysback command in here later (for 5.3) } else { $sysbackcmd="blah"; print "Sysback Comm +and: $sysbackcmd\n"; exec("ssh -q -o ConnectTimeOut=5 $lpar \"$sysbackcmd\" +"); } # exit child process exit 0; } } else { # too much child labor! queue for later under complete_backu +p unshift(@queue,$lpar); }

Replies are listed 'Best First'.
Re: Forking Queue with Pipe (grabbing stderr)
by almut (Canon) on Jan 15, 2009 at 22:25 UTC

    In case you don't need to differentiate between whether the output originated from stdout or stderr, it should be sufficient to redirect stderr to stdout (i.e. ... 2>&1) for the command that you run in the child process.

Re: Forking Queue with Pipe (grabbing stderr)
by jwkrahn (Abbot) on Jan 15, 2009 at 23:55 UTC

    I don't know about your STDERR problem but...

    my $lpar = shift; if ( ( scalar keys %children ) < $max_children ) { my $pid = (open($lpar,"-|"));

    You are apparently passing a file name to the subroutine and then overwritting that file name with a filehandle which you then try to use as a file name in subsequent code.