8

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

4

3 回答 3

20

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

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

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

如果您真的想将该值转换为有符号数量,则必须根据第 16 位进行一些位旋转。

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

另见SO 774048SO 179565

于 2010-04-28T02:31:42.460 回答
10

Perl 以与 C 运行时库宏相同的方式返回子进程退出代码WEXITSTATUS,其中有以下描述wait(2)

   WEXITSTATUS(状态)
          计算为返回码的最低有效八位
          终止的孩子的,可能已被设置为
          调用 exit() 的参数或作为 return 的参数
          主程序中的语句。这个宏只能被评估
          如果 WIFEXITED 返回非零。

这里重要的部分是最低有效八位。这就是为什么您会得到 255 的退出代码。perlvar手册页描述$?如下:

   美元?最后一个管道关闭返回的状态,反引号 ('') com-
           命令,成功调用 wait() 或 waitpid(),或从系统
           tem() 运算符。这只是返回的 16 位状态字
           通过 wait() 系统调用(或者被编成看起来像它)。
           因此,子进程的退出值实际上是(“$?>> 8”),
           并且 "$? & 127" 给出进程死亡的信号(如果有的话)
           from, and "$? & 128" 报告是否有核心转储。

这里没有对退出代码中的负数进行特殊处理。

于 2010-04-28T02:42:00.053 回答
0

你用什么方式转移它?请提供代码示例。

还:

perldoc -f system

给出了一个非常容易理解的例子来说明如何处理 $?

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

退出值应在 0 到 255 之间。您的移位与计算机实际存储负值的方式相结合,应该可以提供一些见解。

于 2010-04-28T02:25:43.197 回答