basically i wanted to execute a system command and get its stderr, stdout, and return value. so i invoke the command with backticks in two different subroutines, one of which redirects STDERR to a variable, and the other doesnt.
when i dont touch stderr, the invoked command prints the command's stderr to the script stderr. but when i try to capture the script stderr, the command's stderr disappears altogether. this baffles me, because if the script itself sends to stderr (ie: the warn builtin), it gets captured just fine.
as i said, this is purely an academic question, but why is this happening?#!/usr/bin/perl -w use strict; use Data::Dumper; # execute command without capturing STDERR sub exec_nocap { # execute command via backticks, getting output (STDOUT) and retur +n value my $command = shift; my $out = `$command`; my $return = $?; # dump everything (in an anonymous hash) print Dumper { 'Return value' => $return, 'STDOUT' => $out, }; } # execute command, capturing STDERR sub exec_cap { # dupe STDERR, to be restored later open(my $stderr, ">&", \*STDERR) or do { print "Can't dupe STDERR: + $!\n"; exit; }; # close first (according to the perldocs) close(STDERR) or die "Can't close STDERR: $!\n"; # redirect STDERR to in-memory scalar my $err; open(STDERR, '>', \$err) or do { print "Can't redirect STDERR: $!\ +n"; exit; }; # just to demonstrate that STDERR capturing is working warn('this is a warning'); # execute command via backticks, getting output (STDOUT) and retur +n value my $command = shift; my $out = `$command`; my $return = $?; # restore original STDERR open(STDERR, ">&", $stderr) or do { print "Can't restore STDERR: $!\ +n"; exit; }; print Dumper({ 'Return value' => $return, 'STDOUT' => $out, 'Redirected STDERR' => $err, }); } exec_nocap('perl -e "die(\'this is a fatal error\')"'); print "\n"x5; exec_cap('perl -e "die(\'this is a fatal error\')"');
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |