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

Perls系统中的退出状态与Bash中的不同,bash,perl,samba,Bash,Perl,Samba,我想检查一下,用户是否有访问某个samba共享的权限。我目前正在使用version4.3.11-Ubuntu中的smbclient命令执行此操作 显然,使用退出状态评估成功不是一个好主意,如本问题所述: 不过我还是有一些奇怪的行为。当使用Perlssystem函数调用程序时,我会得到不同的退出状态 perldoc-f系统告诉我: 返回值是由返回的程序的退出状态 “等等”电话 从命令行调用时,我得到退出1 user@host:~$ smbclient //server/share MyFalseP

我想检查一下,用户是否有访问某个samba共享的权限。我目前正在使用
version4.3.11-Ubuntu
中的
smbclient
命令执行此操作

显然,使用
退出
状态评估成功不是一个好主意,如本问题所述:

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

perldoc-f系统
告诉我:

返回值是由返回的程序的退出状态 “等等”电话

从命令行调用时,我得到
退出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时,我得到
退出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

注意:如果使用正确的凭据,我将同时获得
退出0
(Bash和Perl)

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


我在Ubuntu 16.04上使用Perl v5.22。

这没有很好的文档记录,最有用的信息在 这是怎么说的

  • $CHILD\u错误
  • 美元

    最后一个管道关闭、backtick命令、成功调用
    wait()
    waitpid()
    或从
    system()
    操作员返回的状态。这只是由传统的Unix
    wait()
    系统调用返回的16位状态字(或者按照它的样子进行了修改)。因此,子流程的退出值实际上是(
    $?>>8
    ),而
    $&127
    给出进程终止的信号(如果有),并且
    $?&128
    报告是否存在内核转储


因此,
系统
的返回值256对应于退出值256>>8,这是您期望的1。这没有很好的文档记录,最有用的信息在 这是怎么说的

  • $CHILD\u错误
  • 美元

    最后一个管道关闭、backtick命令、成功调用
    wait()
    waitpid()
    或从
    system()
    操作员返回的状态。这只是由传统的Unix
    wait()
    系统调用返回的16位状态字(或者按照它的样子进行了修改)。因此,子流程的退出值实际上是(
    $?>>8
    ),而
    $&127
    给出进程终止的信号(如果有),并且
    $?&128
    报告是否存在内核转储

因此,
系统
的返回值256对应于退出值256>>8,这是您期望的1。

系统返回的退出状态是一个两字节的数字,它将程序返回的退出代码打包为高位,而如果进程被信号终止,则设置低位8位。低7位是信号号,第8位显示磁芯是否被转储

因此,要获得程序的实际退出,请按照您引用的文档中的下一句话执行

要获得实际的退出值,请右移8

256>>8
给了我们
1

系统
的返回信息可在中找到,查询方式如中所述

最好在清除之前立即保存或检查返回值


通过直接返回程序的退出值,可以避免位移位。谢谢你的评论。为了研究信号,我们仍然需要
$?
,但这种情况出现的频率要低得多。该模块简化了
系统
qx
的使用和错误检查。

系统返回的退出状态是一个两字节的数字,它将程序返回的退出代码打包为高位,而如果进程被信号终止,则设置低位8位。低7位是信号号,第8位显示磁芯是否被转储

因此,要获得程序的实际退出,请按照您引用的文档中的下一句话执行

要获得实际的退出值,请右移8

256>>8
给了我们
1

系统
的返回信息可在中找到,查询方式如中所述

最好在清除之前立即保存或检查返回值



通过直接返回程序的退出值,可以避免位移位。谢谢你的评论。为了研究信号,我们仍然需要
$?
,但这种情况出现的频率要低得多。该模块简化了
系统
qx
的使用和错误检查。

这出乎意料地复杂。这里应该提到的是:我读过你之前引用的句子。你的解释对理解文档有很大帮助。非常感谢。CPAN上是否没有提供不需要位操作的接口的模块?这对于以后需要查看此代码的任何人来说都是一件痛苦的事情。“如果系统返回值不为零,您可以查询变量$?”无需检查
$?
以及
系统的返回值:
:它们是相同的。@Borodin我的意思是将
$?
检查与最常做的事情联系起来,
系统(…)==0或…
(或
系统(…)和…
)。我的意思是人们通常首先检查
系统的返回。这可能有点笨拙:(@BorisDäppen您提到的链接讨论了在
$?
中具有状态的调用之间的差异,因此我想说,是的,您希望提到这一点是对的。我不知道有哪些模块会分割命令的实际退出,但有许多模块会将
系统
(或
qx
)到尼斯
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;
}