繁体   English   中英

如何在Perl中捕获输出和退出代码时执行外部脚本?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM