Как обойти ограничение диапазона 0-255 для sys.exit () в python? - PullRequest
7 голосов
/ 15 декабря 2010

В python (в системе Linux) я запускаю команду, используя os.system(), и получаю код возврата. Если этот код возврата отличается от 0, я хотел бы завершить программу с тем же кодом возврата. Итак, я написал:

ret = os.system(cmd)
if ret != 0:
   print "exit with status %s" % ret
   sys.exit(ret)

Когда код возврата меньше 256, он работает нормально, но когда он больше 255, используется код выхода 0. Как я могу заставить sys.exit () принимать коды больше 255?

Изменить: лимит на самом деле 255

На самом деле, переменная ret получает 256, но sys.exit() не может использовать его, поэтому программа возвращает 0. Когда я запускаю cmd вручную, я вижу, что он возвращает 1, а не 256.

Ответы [ 3 ]

6 голосов
/ 15 декабря 2010

На самом деле, документация указывает, что

индикация состояния выхода: 16-разрядное число, младший байт которого является номером сигнала, который убил процесс, а старший байт - это состояние выхода (если номер сигнала равен нулю); старший бит младшего байта устанавливается, если был создан файл ядра.

Поэтому мне нужно обработать число, возвращаемое sys.exit (), чтобы получить реальный статус выхода, например:

ret = os.system(cmd)
# Ignore the first byte, use the second one only
ret = ret >> 8
if ret != 0:
   print "exit with status %s" % ret
   sys.exit(ret)

И теперь это работает: ret содержит 1 вместо 256.

3 голосов
/ 15 декабря 2010

Вы не можете не должны, потому что система резервирует коды выхода выше 128 для себя. Если код возврата от 0 до 127, это означает, что программа вышла сама. Если код возврата выше 128, это означает, что программа была прервана системным сигналом (например, SIGKILL или SIGTERM). Номер сигнала - код результата минус 128.

Вам нужно будет обнаружить это и сделать какой-то другой вид индикации вывода, я думаю. Возможно, выведите код возврата в STDOUT, а затем вернитесь либо с 0 (нормальный выход, нормальный вывод), либо с 1 (cmd имел ненулевое возвращаемое значение, выход означает что-то).

edit: Очевидно (из этого комментария ), Python умнее, чем сценарий оболочки ... Чтобы вернуть его в обычный код выхода Linux, попробуйте следующее:

subprocess_exit_code = (ret >> 8) & 0x7f
subprocess_signal_number = ret & 0xff

if subpprocess_signal_number == 0:
  exit_code = subprocess_exit_code
else:
  exit_code = 128 + subprocess_signal_number

Хотя это игнорирует информацию о дампе ядра.

0 голосов
/ 15 декабря 2010

У меня работает (CentOS 5.5, Python 2.6.5):

$ python
>>> import sys
>>> sys.exit(245)
$ echo $?
245
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...