【问题标题】:How do I execute an external script while capturing both output and exit code in Perl?如何在 Perl 中捕获输出和退出代码时执行外部脚本?
【发布时间】:2010-02-05 09:17:42
【问题描述】:

我正在尝试从 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 切换回原始代码。

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

【问题讨论】:

    标签: perl stdout stderr exit-code


    【解决方案1】:

    尝试使用$?.e.g.

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

    【讨论】:

    • 退出码是$?中的高字节,所以需要$?>> 8
    【解决方案2】:

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

     use IPC::System::Simple qw(capturex $EXITVAL);
    
     my $output = capturex( "some_command", @args );
     my $exit   = $EXITVAL;
    

    【讨论】:

      【解决方案3】:
       my $output = `svn info $url/tags/$tag 2>&1`;
      

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

      您确定退出代码丢失了吗?当我尝试这个时,我会在$? 中获得退出代码。

      【讨论】:

      • 嗯,退出码是$?中的高字节,所以你需要$? >> 8
      【解决方案4】:

      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: $@";
      }
      

      【讨论】:

      • run3 的返回值只处理文件句柄的处理。对进程的退出代码没有意义。
      猜你喜欢
      • 2013-08-28
      • 2011-07-15
      • 2017-07-05
      • 2010-09-11
      • 2010-11-27
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多