如何从 IPC::Run3 测试退出状态
How to test the exit status from IPC::Run3
我正在尝试测试 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。
谢谢。
需要注意的几点。
首先,对于直接问题,IPC::Run3 文档告诉我们
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调用以捕获该异常
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
本身的状态,因此 $?
。来自文档
Note that a true return value from run3
doesn't mean that the command
had a successful exit code. Hence you should always check $?
.
对于变量 $@
和 $?
,请参阅 General Variables in perlvar,以及 system
和 eval
页。
这个的最小版本是删除 eval
(和 $@
检查)并期望程序 die
如果 run3
有问题,应该很少见,并检查(并打印)$?
.
的值
关于 run3
界面的注释。使用 \@cmd
它期望 @cmd
包含一个分解成单词的命令,第一个元素是程序和其余参数。在 $cmd
接口支持的字符串中编写命令与在数组中编写命令是有区别的。请参阅 system 了解说明。
哪种选择最适合您取决于您的确切需求。这里有一些选项。也许先尝试 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 以获得更大的功率。
我正在尝试测试 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。
谢谢。
需要注意的几点。
首先,对于直接问题,IPC::Run3 文档告诉我们
run3
throws an exception if the wrappedsystem
call returned-1
or anything went wrong withrun3
's processing of filehandles. Otherwise it returns true. It leaves$?
intact for inspection of exit and wait status.
您询问的错误属于此类,您需要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
本身的状态,因此 $?
。来自文档
Note that a true return value from
run3
doesn't mean that the command had a successful exit code. Hence you should always check$?
.
对于变量 $@
和 $?
,请参阅 General Variables in perlvar,以及 system
和 eval
页。
这个的最小版本是删除 eval
(和 $@
检查)并期望程序 die
如果 run3
有问题,应该很少见,并检查(并打印)$?
.
关于 run3
界面的注释。使用 \@cmd
它期望 @cmd
包含一个分解成单词的命令,第一个元素是程序和其余参数。在 $cmd
接口支持的字符串中编写命令与在数组中编写命令是有区别的。请参阅 system 了解说明。
哪种选择最适合您取决于您的确切需求。这里有一些选项。也许先尝试 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 以获得更大的功率。