如何从 IPC::Run3 测试退出状态 [英] How to test the exit status from IPC::Run3

查看:59
本文介绍了如何从 IPC::Run3 测试退出状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to test the Perl module IPC::Run3 but having difficulty in checking whether a command is failed or successful.
I know that IPC::Run3 issues an exit code if something is wrong with its arguments, but what about if the arguments are ok but the command does not exist? How can I test the following example?

有一个子程序来调用 Run3

Having a subroutine to call 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 代替.

when command $cmds[0] below is executed (the ls command of *nix systems) it prints OK as expected, but with command $cmds[1] it just says No such file or directory at ./testrun3.pl line 18. With a test to the exit code I want it to print Something is wrong instead.

#!/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.

Or what would be the best alternative to IPC::Run3 in cases like this? This is just an oversimplification of the process, but eventually I would like to capture STDERR and STDOUT for more complex situations.

谢谢.

推荐答案

一些要点.

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

First, for the direct question, the IPC::Run3 documentation tells us that

run3 将抛出异常's 处理文件句柄.否则返回真.它保留 $? 完整以检查退出和等待状态.

run3 throws an exception if the wrapped system call returned -1 or anything went wrong with run3's processing of filehandles. Otherwise it returns true. It leaves $? intact for inspection of exit and wait status.

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

The error you ask about is of that kind and you need to eval the call to catch that exception

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 无法执行.例如当调用一个不存在的程序时.

You can now print your own messages inside if ($@) { } block, when errors happen where the underlying system fails to execute. Such as when a non-existing program is called.

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

Here $@ relates to eval while $? to system. So if run3 didn't have a problem and $@ is false next we check the status of system itself, thus $?. From docs

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

Note that a true return value from run3 doesn't mean that the command had a successful exit code. Hence you should always check $?.

对于变量 $@$? 参见 perlvar 中的一般变量,以及 systemeval 页面.

For variables $@ and $? see General Variables in perlvar, and system and eval pages.

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

A minimal version of this is to drop eval (and $@ check) and expect the program to die if run3 had problems, what should be rare, and to check (and print) the value of $?.

关于run3 界面的说明.使用 \@cmd 它期望 @cmd 包含一个分解成单词的命令,第一个元素是程序和其余的参数.在$cmd 接口支持的字符串中写入命令和在数组中写入命令是有区别的.请参阅 system 了解说明.

A note on run3 interface. With \@cmd it expects @cmd to contain a command broken into words, the first element being the program and the rest arguments. There is a difference between writing a command in a string, supported by $cmd interface, and in an array. See system for explanation.

哪种替代方案最适合您取决于您​​的确切需求.这里有一些选项.也许首先尝试 IPC::System::Simple(但盘子上没有STDERR).为了干净地捕获各种输出 Capture::Tiny 很棒.在另一端有 IPC::Run 获得更大的力量.

Which alternative would suit you best depends on your exact needs. Here are some options. Perhaps first try IPC::System::Simple (but no STDERR on the platter). For cleanly capturing all kinds of output Capture::Tiny is great. On the other end there is IPC::Run for far more power.

这篇关于如何从 IPC::Run3 测试退出状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆