How can I run an external command and capture its

2019-01-09 12:27发布

问题:

I'm new to Perl and want to know of a way to run an external command (call it prg) in the following scenarios:

  1. Run prg, get its stdout only.
  2. Run prg, get its stderr only.
  3. Run prg, get its stdout and stderr, separately.

回答1:

You can use the backtics to execute your external program and capture its stdout and stderr.

By default the backticks discard the stderr and return only the stdout of the external program.So

$output = `cmd`;

Will capture the stdout of the program cmd and discard stderr.

To capture only stderr you can use the shell's file descriptors as:

$output = `cmd 2>&1 1>/dev/null`;

To capture both stdout and stderr you can do:

$output = `cmd 2>&1`;

Using the above you'll not be able to differenciate stderr from stdout. To separte stdout from stderr can redirect both to a separate file and read the files:

`cmd 1>stdout.txt 2>stderr.txt`;


回答2:

You can use IPC::Open3 or IPC::Run. Also, read How can I capture STDERR from an external command from perlfaq8.



回答3:

In most cases you can use the qx// operator (or backticks). It interpolates strings and executes them with the shell, so you can use redirections.

  • To capture a command's STDOUT (STDERR is unaffected):

    $output = `cmd`;
    
  • To capture a command's STDERR and STDOUT together:

    $output = `cmd 2>&1`;
    
  • To capture a command's STDERR but discard its STDOUT (ordering is important here):

    $output = `cmd 2>&1 1>/dev/null`;
    
  • To exchange a command's STDOUT and STDERR in order to capture the STDERR but leave its STDOUT to come out the old STDERR:

    $output = `cmd 3>&1 1>&2 2>&3 3>&-`;
    
  • To read both a command's STDOUT and its STDERR separately, it's easiest to redirect them separately to files, and then read from those files when the program is done:

    system("program args 1>program.stdout 2>program.stderr");