Reading STDERR from a Program
Problem
You want to run a program as you would with
system
, backticks, or open
, but
you don’t want its STDERR to be sent to your STDERR. You would
like to be able to either ignore or read the STDERR.
Solution
Use the shell’s numeric redirection and duplication syntax for
file descriptors. (We don’t check the return value from
open
here, to make the examples easier to read,
but you should always check it in your programs!)
To capture a command’s STDERR and STDOUT together:
$output = `cmd 2>&1`; # with backticks # or $pid = open(PH, "cmd 2>&1 |"); # with an open pipe while (<PH>) { } # plus a read
To capture a command’s STDOUT and discard its STDERR:
$output = `cmd 2>/dev/null`; # with backticks # or $pid = open(PH, "cmd 2>/dev/null |"); # with an open pipe while (<PH>) { } # plus a read
To capture a command’s STDERR and discard its STDOUT:
$output = `cmd 2>&1 1>/dev/null`; # with backticks # or $pid = open(PH, "cmd 2>&1 1>/dev/null |"); # with an open pipe while (<PH>) { } # plus a read
To exchange a command’s STDOUT and STDERR, i.e., capture the STDERR but have its STDOUT come out on our old STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`; # with backticks # or $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|"); # 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 ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.