Let\'s say I want to run an external program from my script with backticks and at the same time I want to capture both STDOUT and STDERR but in two different variables. How can
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
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.
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.