How to capture both STDOUT and STDERR in two different variables using Backticks in Perl

放肆的年华 提交于 2019-12-03 07:59:32
Pablo Marin-Garcia

In the Perl FAQ you have different options depending how do you want to proceed:

http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f

You needn't go all the way to open3, which IIRC is only for when you need to read and write to an external command, and even then there are other methods.

For your problem I suggest using Capture::Tiny, which can capture (or even tee) the STDOUT and STDERR from anything run inside its block. For example, per your question:

#!/usr/bin/env perl

use strict;
use warnings;

use Capture::Tiny qw/capture/;

...

my ($stdout, $stderr) = capture {
  system ( "snmpwalk -v $version -c $community $hostname $oid" );
};

For another example consider this functioning code:

#!/usr/bin/env perl

use strict;
use warnings;

use Capture::Tiny qw/capture/;

my ($stdout, $stderr) = capture {
  system ( "echo 'hello'" );
  system ( "date" );
  warn "Arg1!";
};

print "STDOUT:\n$stdout";
print "STDERR:\n$stderr";

which just gave me:

STDOUT:
hello
Mon Dec 19 23:59:06 CST 2011
STDERR:
Arg1! at ./test.pl line 11.

The only way to do this with backticks is to redirect to a file inside the shell command:

   my $cmd = `snmpwalk -v $version -c $community $hostname $oid 2>error.dat`;

If you want to capture the STDERR inside your script, you need IPC::Open3 instead of backticks

IO::CaptureOutput

is a very convenient wrapper for what you want to do.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!