Perls 系统中的退出状态与 Bash 中的不同

Different Exit Status in Perls system than in Bash

我想检查用户是否有访问某个 samba 共享的权限。我目前正在使用 Version 4.3.11-Ubuntu.

中的命令 smbclient 执行此操作

显然,使用 exit 状态来评估成功不是一个好主意,如以下问题所述:Exit codes of smbclient

但是我还是有一些奇怪的行为。使用 Perls system 函数调用程序时,我得到不同的退出状态。

perldoc -f system 告诉我这个:

The return value is the exit status of the program as returned by the "wait" call.

从命令行调用时,我得到 EXIT 1

user@host:~$ smbclient //server/share MyFalsePassword --user=any.user -c "cd somefolder;"; echo "EXIT $?"
WARNING: The "syslog" option is deprecated
session setup failed: NT_STATUS_LOGON_FAILURE
EXIT 1

调用相同的 whitin Perl 我得到 EXIT 256

user@host:~$ perl -E 'say "EXIT " . system("smbclient //server/share MyFalsePassword --user=any.user -c \"cd somefolder;\"");'
WARNING: The "syslog" option is deprecated
session setup failed: NT_STATUS_LOGON_FAILURE
EXIT 256

我在变量 $? whitin Perl 中也有值 256

注意:如果我使用正确的凭据,我在(Bash 和 Perl)中都会得到 EXIT 0

我的问题: 如果我使用错误的凭据,为什么我从 Bash 和 Perl 获得不同的退出状态?如何检查正确?

我在 Ubuntu 16.04.

上使用 Perl v5.22

这没有很好的记录,最有用的信息在 perldoc perlvar 这表示

  • $CHILD_ERROR
  • $?

    The status returned by the last pipe close, backtick command, successful call to wait() or waitpid(), or from the system() operator. This is just the 16-bit status word returned by the traditional Unix wait() system call (or else is made up to look like it). Thus, the exit value of the subprocess is really ($? >> 8 ), and $? & 127 gives which signal, if any, the process died from, and $? & 128 reports whether there was a core dump.

因此 system 中的 return 值 256 对应于退出值 256 >> 8,这是您期望的 1

退出状态 returned by system是一个两字节的数字,它封装了退出代码returned by system编程到高位,而如果进程被信号杀死,则设置低 8 位。低7位是信号编号,第8位表示内核是否被转储。

因此,要真正退出程序,请按照您引用的文档中的下一句话说的做

To get the actual exit value, shift right by eight

256 >> 8 给我们 1

system 的 return 在 variable $?, interrogated as spelled out in system

中可用
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;
}

return 最好在清除之前立即保存或$? 检查。


注释的using IPC::System::Simple, which returns the program's exit value directly. Thanks to daxim可以避免移位。为了调查我们仍然需要 $? 的信号,但这出现的频率要低得多。该模块简化了 systemqx 使用和错误检查。