Почему код выхода 255 вместо -1 в Perl? - PullRequest
7 голосов
/ 28 апреля 2010

Почему при переносе кода выхода $? В Perl на восемь я получаю 255, когда ожидаю, что он будет равен -1?

Ответы [ 3 ]

20 голосов
/ 28 апреля 2010

Состояние выхода, возвращаемое функцией wait (), является 16-битным значением. Из этих 16 битов старшие 8 битов берутся из младших 8 битов значения, возвращаемого функцией exit (), или значения, возвращаемого из main(). Если программа умирает естественным образом, младшие 8 битов из 16 равны нулю. Если программа умирает из-за сигнала, младшие 8 битов кодируют номер сигнала и бит, указывающий, произошел ли дамп ядра. С сигналом состояние выхода обрабатывается как ноль - программы, подобные оболочке, имеют тенденцию интерпретировать ненулевые биты младшего разряда как сбой.

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

Большинство машин на самом деле хранят 16-битное значение в 32-битном целом числе, и это обрабатывается с помощью арифметики без знака. Старшие 8 битов из 16 могут быть все 1, если процесс завершился с «exit (-1)», но это будет выглядеть как 255, если смещено вправо на 8 бит.

Если вы действительно хотите преобразовать значение в количество со знаком, вам придется выполнить некоторую перестановку битов на основе 16-го бита.

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

См. Также SO 774048 и SO 179565 .

10 голосов
/ 28 апреля 2010

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.

Важной частью здесь являются младшие 8 бит . Вот почему вы получаете код выхода 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 голосов
/ 28 апреля 2010

В какую сторону вы меняете это? Пожалуйста, предоставьте пример кода.

также:

perldoc -f system

дает очень простой для понимания пример того, что делать с $?

Также http://www.gnu.org/s/libc/manual/html_node/Exit-Status.html

Выходные значения должны быть в диапазоне от 0 до 255. Ваше смещение в сочетании с тем, как на самом деле хранятся отрицательные значения на компьютере, должно дать некоторое представление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...