假设我想从我的脚本中运行一个带有反引号的外部程序,同时我想同时捕获 STDOUT 和 STDERR,但使用两个不同的变量。我怎样才能做到这一点?例如,如果我运行这个脚本......
my $cmd = `snmpwalk -v $version -c $community $hostname $oid`;
...如果没有错误,一切正常,但如果命令引发错误,则此错误将打印在命令行上,我不希望这种情况发生。我也想捕获错误。无需在屏幕上打印任何内容。有任何想法吗?
假设我想从我的脚本中运行一个带有反引号的外部程序,同时我想同时捕获 STDOUT 和 STDERR,但使用两个不同的变量。我怎样才能做到这一点?例如,如果我运行这个脚本......
my $cmd = `snmpwalk -v $version -c $community $hostname $oid`;
...如果没有错误,一切正常,但如果命令引发错误,则此错误将打印在命令行上,我不希望这种情况发生。我也想捕获错误。无需在屏幕上打印任何内容。有任何想法吗?
您不必一直到open3
,IIRC 仅适用于您需要读取和写入外部命令的情况,即使那样还有其他方法。
对于您的问题,我建议使用Capture::Tiny
,它可以从其块内运行的任何东西中捕获(甚至是 tee)STDOUT 和 STDERR。例如,根据您的问题:
#!/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" );
};
对于另一个示例,请考虑以下功能代码:
#!/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";
这只是给了我:
STDOUT:
hello
Mon Dec 19 23:59:06 CST 2011
STDERR:
Arg1! at ./test.pl line 11.
使用反引号执行此操作的唯一方法是重定向到 shell 命令内的文件:
my $cmd = `snmpwalk -v $version -c $community $hostname $oid 2>error.dat`;
如果要在脚本中捕获 STDERR,则需要IPC::Open3而不是反引号
在 Perl 常见问题解答中,您有不同的选项,具体取决于您要如何进行:
http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f
是您想要做的非常方便的包装器。