![]() |
|
There's more than one way to do things | |
PerlMonks |
How can I capture STDERR from an external command?by faq_monk (Initiate) |
on Oct 08, 1999 at 00:29 UTC ( [id://730]=perlfaq nodetype: print w/replies, xml ) | Need Help?? |
Current Perl documentation can be found at perldoc.perl.org. Here is our local, out-dated (pre-5.6) version: There are three basic ways of running external commands:
system $cmd; # using system() $output = `$cmd`; # using backticks (``) open (PIPE, "cmd |"); # using open()
With
With any of these, you can change file descriptors before the call:
open(STDOUT, ">logfile"); system("ls"); or you can use Bourne shell file-descriptor redirection:
$output = `$cmd 2>some_file`; open (PIPE, "cmd 2>some_file |"); You can also use file-descriptor redirection to make STDERR a duplicate of STDOUT:
$output = `$cmd 2>&1`; open (PIPE, "cmd 2>&1 |"); Note that you cannot simply open STDERR to be a dup of STDOUT in your Perl program and avoid calling the shell to do the redirection. This doesn't work:
open(STDERR, ">&STDOUT"); $alloutput = `cmd args`; # stderr still escapes
This fails because the
Note that you must use Bourne shell (sh(1)) redirection syntax in backticks, not
$output = `cmd 2>&1`; # either with backticks $pid = open(PH, "cmd 2>&1 |"); # or with an open pipe while (<PH>) { } # plus a read To capture a command's STDOUT but discard its STDERR:
$output = `cmd 2>/dev/null`; # either with backticks $pid = open(PH, "cmd 2>/dev/null |"); # or with an open pipe while (<PH>) { } # plus a read To capture a command's STDERR but discard its STDOUT:
$output = `cmd 2>&1 1>/dev/null`; # either with backticks $pid = open(PH, "cmd 2>&1 1>/dev/null |"); # or with an open pipe while (<PH>) { } # plus a read To exchange a command's STDOUT and STDERR in order to capture the STDERR but leave its STDOUT to come out our old STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`; # either with backticks $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe while (<PH>) { } # plus a read To read both a command's STDOUT and its STDERR separately, it's easiest and safest to redirect them separately to files, and then read from those files when the program is done:
system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr"); Ordering is important in all these examples. That's because the shell processes file descriptor redirections in strictly left to right order.
system("prog args 1>tmpfile 2>&1"); system("prog args 2>&1 1>tmpfile"); The first command sends both standard out and standard error to the temporary file. The second command sends only the old standard output there, and the old standard error shows up on the old standard out.
|
|