7

我正在尝试从 Perl 脚本中检查是否存在 SVN 标记。所以我尝试调用svn info $url,读取退出代码并抑制标准输出和标准错误流。但是,我很难优雅地做到这一点(可能有更好的方法向 SVN 询问标签,但这不是重点):

my $output = `svn info $url/tags/$tag`;

这会抑制输出,同时将其放入$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 切换回原始代码。

那么,有没有更优雅的解决方案呢?

4

4 回答 4

8

尝试使用$?.eg

my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;

于 2010-02-05T09:33:06.543 回答
3

当您尝试使用IPC::System::Simple时会发生什么?该模块处理这类问题的大部分细节:

 use IPC::System::Simple qw(capturex $EXITVAL);

 my $output = capturex( "some_command", @args );
 my $exit   = $EXITVAL;
于 2010-02-05T11:10:58.910 回答
1
 my $output = `svn info $url/tags/$tag 2>&1`;

这会抑制 STDERR 和 STDOUT 并将它们都放入 $output 中。退出代码再次丢失

您确定退出代码丢失了吗?当我尝试这个时,我得到了退出代码$?

于 2010-02-05T09:45:49.513 回答
0

模块IPC::Run3对输入和输出提供了非常细粒度的控制。

use IPC::Run3;
run3 \@cmd, \$in, \$out, \$err;

您可以将相同的变量传递给\$outand \$err,它会按照您的预期,结合两个流。输入是不必要的,因此您可以传递undef(“从父进程继承”)或\undef(“关闭的文件句柄”。)

IPC::Run3::run3()根据退出代码返回真或假,并将子进程的实际退出代码保留在$?“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: $@";
}
于 2010-02-05T11:23:27.900 回答