system()返回错误的退出代码

时间:2017-06-17 13:06:25

标签: perl

我正在使用system来调用外部应用程序,我需要解释其退出代码。

我知道system返回命令的退出代码乘以256,但在foo.bat中我写exit 256时结果为零。

为什么会这样?

3 个答案:

答案 0 :(得分:5)

Windows使用32位退出代码,因此exit 256完全有效。

>cmd /c exit 256

>echo %ERRORLEVEL%
256

但是,Perl只保留最低8位。

>perl -e"system 'exit 256'; CORE::say $?>>8"
0

>perl -e"system 'exit 266'; CORE::say $?>>8"
10

这是一个Perl缺陷,没有充分的理由。如果您使用Win32::Process代替system,则可以获得正确的退出代码。

>perl -MWin32::Process=NORMAL_PRIORITY_CLASS,INFINITE -e"Win32::Process::Create(my $proc, $ENV{COMSPEC}, 'cmd /c exit 256', 0, NORMAL_PRIORITY_CLASS, '.') or die $^E; $proc->Wait(INFINITE); $proc->GetExitCode(my $exit_code); CORE::say $exit_code;"
256

答案 1 :(得分:1)

返回码是从0到255的单字节值。

检查system来电状态的最可靠方法是检查$?。它已记录在perldoc perlfunc中,就像这样

if ($? == -1) {
    print "failed to execute: $!\n";
}
elsif ($? & 127) {
    printf "child died with signal %d, %s coredump\n",
        ($? & 127),  ($? & 128) ? 'with' : 'without';
}
else {
    printf "child exited with value %d\n", $? >> 8;
}

答案 2 :(得分:-1)

通过检查$?可以获得所有失败的可能性。

$exit_val    = $? >> 8;
$signal      = $? & 127;
$dumped_core = $? & 128;`

引用perldoc perlvar

  
      
  • $ CHILD_ERROR
  •   
  • $?

         

    最后一个管道关闭,反引号(``)命令,成功调用wait()waitpid()system()运算符返回的状态。这只是传统的Unix wait()系统调用返回的16位状态字(或者看起来像是这样)。因此,子进程的退出值实际上是($? >> 8),$? & 127给出了进程死亡的信号(如果有的话),$? & 128报告是否存在核心转储。

  •