2010-04-28 183 views
7

为什么当我将Perl中的退出代码$ ?,在Perl中移位8位时,我预计它会变为-1时是255?为什么在Perl中退出代码255而不是-1?

+6

也许你可以解释为什么你期望退出代码是-1。 – 2010-04-28 02:25:19

+3

请显示Perl代码。什么程序/脚本'发出'退出代码,哪个脚本报告它? – lexu 2010-04-28 02:27:01

+4

'perl -e“exit -1”; echo $?'=> 255。 – jrockway 2010-04-28 04:29:13

回答

20

'wait()'返回的退出状态是一个16位的值。在这16位中,高位8位来自'exit()'返回值的低8位 - 或者从main()返回的值。如果程序自然死亡,则16的低8位全部为零。如果程序因信号而死亡,则低位8位将对信号编号进行编码,并指示是否发生核心转储。对于一个信号,退出状态被视为零 - 类似shell的程序倾向于将低位非零解释为失败。

15  8 7  0 Bit Position 
+-----------------+ 
| exit | signal | 
+-----------------+ 

大多数机器实际上将32位整数中的16位值存储起来,并且这是用无符号算术处理的。如果进程用'exit(-1)'退出,则16的高阶8位可能全为1,但当向右移位8位时,该进程将显示为255。

如果您确实想将该值转换为带符号的数量,则必须根据第16位做一些位调换。

$status >>= 8; 
($status & 0x80) ? -(0x100 - ($status & 0xFF)) : $status; 

又见SO 774048SO 179565

0

你在哪个方向移动它?请提供一个代码示例。

也:

perldoc -f system 

给出了如何处理$做一个很容易理解的例子吗?

此外,http://www.gnu.org/s/libc/manual/html_node/Exit-Status.html

退出值应255之间0和你的换档与如何负值由计算机实际上是存储应该给一些见解组合。

+0

我正在向右移动8位 – syker 2010-04-28 05:14:27

10

的Perl中相同的方式为C运行时库的宏WEXITSTATUS,其具有在wait(2)下面的描述返回一个子流程退出代码:

 
    WEXITSTATUS(status) 
      evaluates to the least significant eight bits of the return code 
      of the child which terminated, which may have been set as the 
      argument to a call to exit() or as the argument for a return 
      statement in the main program. This macro can only be evaluated 
      if WIFEXITED returned non-zero. 

重要这里部分是至少显著八位。这就是为什么你得到255的退出代码perlvar手册页介绍$?如下:

 
    $?  The status returned by the last pipe close, backtick (‘‘) com- 
      mand, successful call to wait() or waitpid(), or from the sys- 
      tem() operator. This is just the 16-bit status word returned 
      by the 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. 

这里没有特殊的处理在退出代码负数。

+0

太棒了! – syker 2010-04-28 05:15:01