system $cmd; # using system() $output = `$cmd`; # using backticks (``) open (PIPE, "cmd |"); # using open()
With system,
both
STDOUT and
STDERR will go the same place as the script's versions of these, unless the command redirects them. Backticks and open
read
only the
STDOUT of your command.
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 open
makes
STDERR go to where
STDOUT was going at the time of the open.
The backticks then make
STDOUT go to a string, but don't change
STDERR (which still goes to the old
STDOUT).
Note that you must use Bourne shell (sh(1)) redirection syntax in backticks, not
csh!
Details on why Perl's system
and backtick
and pipe opens all use the Bourne shell are in
CPAN/doc/FMTEYEWTK/versus/csh.whynot .
You may also use the IPC::Open3 module (part of the standard perl distribution), but be warned that it has a different order of arguments from IPC::Open2 (see Open3).