[英]How do I execute an external script while capturing both output and exit code in Perl?
我正在尝试从Perl脚本检查SVN标记是否存在。 所以我尝试调用svn info $url
,读取退出代码并禁止标准输出和标准错误流。 但是,我很难优雅地做到这一点(可能有更好的方式向SVN询问标签,但这不是重点:)
my $output = `svn info $url/tags/$tag`;
这会在将$output
放入$output
时抑制$output
。 退出代码丢失。
my $output = `svn info $url/tags/$tag 2>&1`;
这会抑制STDERR和STDOUT,并将它们都放入$output
。 退出代码再次丢失。
my $exitcode = system("svn", "info", "$url/tags/$tag");
这会捕获退出代码,但实际的输出和错误流对用户可见。
open( STDERR, q{>}, "/dev/null" );
open my $fh, q{>}, "/dev/null";
select($fh);
if (system("svn", "info", "$url/tags/$tag") != 0) {
select(STDOUT);
print ("Tag doesn't exist!");
do_something_with_exit();
}
select(STDOUT);
print "Exit code: $exitcode";
这会杀死STDOUT和STDERR并捕获退出代码,但它很难看,因为我必须记住将STDOUT切换回原始状态。
那么,还有更优雅的解决方案吗?
尝试使用$?
。例如
my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;
使用IPC :: System :: Simple尝试时会发生什么? 该模块处理这些问题的大部分细节:
use IPC::System::Simple qw(capturex $EXITVAL);
my $output = capturex( "some_command", @args );
my $exit = $EXITVAL;
my $output = `svn info $url/tags/$tag 2>&1`;
这会抑制STDERR和STDOUT,并将它们都放入$ output。 退出代码再次丢失
你确定退出代码丢失了吗? 当我尝试这个时,我得到$?
的退出代码$?
。
IPC :: Run3模块对输入和输出进行了非常细粒度的控制。
use IPC::Run3;
run3 \@cmd, \$in, \$out, \$err;
您可以将相同的变量传递给\\$out
和\\$err
,它将完成您所期望的,组合两个流。 输入是不必要的,因此您可以传递undef
(“从父进程继承”)或\\undef
(“关闭文件句柄”)。
IPC::Run3::run3()
根据退出代码返回true或false,并将子进程的实际退出代码留在$?
按照'perlvar'。
在你的情况下,你会跑
use IPC::Run3
my @cmd = ('svn', 'info', "$url/tags/$tag");
my $out;
my $rv = run3(\@cmd, \undef, \$out, \$out);
if ($rv) {
# process $out
}
else {
die "error: $@";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.