为什么在Perl中退出代码255而不是-1?

syk*_*ker 7 perl exit

为什么当我将退出代码$ ?,在Perl中移位8时,当我期望它为-1时,我得到255?

Jon*_*ler 20

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

15      8 7      0   Bit Position
+-----------------+
|  exit  | signal |
+-----------------+
Run Code Online (Sandbox Code Playgroud)

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

如果您真的想将值转换为有符号数量,则必须根据第16位进行一些比特操作.

$status >>= 8;
($status & 0x80) ? -(0x100 - ($status & 0xFF)) : $status;
Run Code Online (Sandbox Code Playgroud)

另见SO 774048SO 179565.


Gre*_*ill 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.

这里没有特殊处理退出代码中的负数.