【问题标题】:How to test the exit status from IPC::Run3如何测试 IPC::Run3 的退出状态
【发布时间】:2016-11-24 01:52:40
【问题描述】:

我正在尝试测试 Perl 模块 IPC::Run3,但难以检查命令是失败还是成功。
我知道如果 IPC::Run3 的参数有问题,它会发出退出代码,但是如果参数正常但命令不存在怎么办?如何测试以下示例?

有一个子程序来调用 Run3

sub runRun3 {

    my $cmd = shift;
    my ($stdout, $stderr);

    run3($cmd, \undef, \$stdout, \$stderr);

#   if( $? == -1 ) {
    if (! $stdout and ! $stderr) {
        die "Something is wrong";
    } else {
        print "OK \n";
    }

}

当执行下面的命令$cmds[0](*nix 系统的ls 命令)时,它会按预期打印OK,但使用命令$cmds[1] 它只会显示No such file or directory at ./testrun3.pl line 18。 通过对退出代码的测试,我希望它改为打印 Something is wrong

#!/usr/bin/perl

use warnings;
use strict;

use IPC::Run3;

my @cmds = qw(ls silly);

runRun3($cmds[0]);
runRun3($cmds[1]);

或者在这种情况下,IPC::Run3 的最佳替代方案是什么?这只是对过程的过度简化,但最终我想为更复杂的情况捕获 STDERR 和 STDOUT。

谢谢。

【问题讨论】:

    标签: perl exit-code perl-ipc-run


    【解决方案1】:

    需要经历的几点。

    首先,对于直接问题,IPC::Run3 文档告诉我们

    如果包装的system 调用返回-1run3 处理文件句柄出现任何问题,run3 将引发异常。否则返回真。它使$? 完好无损,以便检查退出和等待状态。

    您询问的错误属于此类,您需要eval 调用以捕获该异常

    use warnings 'all';
    use strict;
    use feature 'say';
    
    my ($stdout, $stderr);
    
    my @cmd = ("ls", "-l");
    
    eval { run3 \@cmd, \undef, \$stdout, \$stderr };
    if    ( $@        ) { print "Error: $@";                     }
    elsif ( $? & 0x7F ) { say "Killed by signal ".( $? & 0x7F ); }
    elsif ( $? >> 8   ) { say "Exited with error ".( $? >> 8 );  }
    else                { say "Completed successfully";          }
    

    您现在可以在 if ($@) { } 块内打印您自己的消息,当底层 system 无法执行的错误发生时。例如调用不存在的程序时。

    这里$@eval 相关,而$?system 相关。因此,如果run3 没有问题并且$@ 为假,那么接下来我们检查system 本身的状态,即$?。来自文档

    请注意,run3 的真正返回值并不意味着该命令 有一个成功的退出代码。因此,您应该始终检查$?

    对于变量$@$?,请参见General Variables in perlvarsystemeval 页面。

    一个最小的版本是删除eval(和$@检查)并期望程序die如果run3有问题,应该很少见,并检查(并打印)值$?.

    关于run3 接口的注释。对于\@cmd,它期望@cmd 包含一个分成单词的命令,第一个元素是程序,其余的参数。在$cmd 接口支持的字符串中写入命令和在数组中写入命令是有区别的。解释见system

    哪种选择最适合您取决于您​​的具体需求。这里有一些选项。也许首先尝试IPC::System::Simple(但盘子上没有STDERR)。对于干净地捕获各种输出Capture::Tiny 非常棒。在另一端,IPC::Run 提供更多功能。

    【讨论】:

    • @ikegami 哦,当然,更好地展示这一切(并且正确地)。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 2022-06-21
    • 2021-05-30
    • 2019-09-19
    • 1970-01-01
    相关资源
    最近更新 更多