Коды выхода в Python


207

Я получил сообщение, говорящее script xyz.py returned exit code 0. Что это значит?

Что означают коды выхода в Python? Сколько их там? Какие из них важны?


1
Где вы видите это сообщение?
Джереми Кантрелл

1
@ Джереми В нижней части PythonWin.
Sundeep

Ответы:


223

То, что вы ищете в сценарии, это вызовы sys.exit(). Аргумент этого метода возвращается в среду в качестве кода выхода.

Вполне вероятно, что скрипт никогда не вызывает метод выхода, и что 0 является кодом выхода по умолчанию.


12
Не уверен вообще. В Unix / Linux стандарт таков: выход 0, если все в порядке. Введите команду, затем echo $ ?: если вы прочитали 0, она вернулась без ошибки. Идея состоит в том, чтобы иметь стандартные тесты. Если код xyz.py не обнаружил никакой ошибки, он ДОЛЖЕН вернуть 0!
Бруно фон Пэрис

1
Если вы хотите изменить код выхода, предпочитайте
чистый

101

Из документации дляsys.exit :

Необязательный аргумент arg может быть целым числом, указывающим статус выхода (по умолчанию равен нулю), или объектом другого типа. Если это целое число, ноль считается «успешным завершением», а любое ненулевое значение считается «ненормальным завершением» оболочками и тому подобным. Большинство систем требуют, чтобы он находился в диапазоне 0-127, и в противном случае дают неопределенные результаты. В некоторых системах есть соглашение о назначении определенных значений определенным кодам выхода, но они, как правило, недостаточно развиты; Программы Unix обычно используют 2 для ошибок синтаксиса командной строки и 1 для всех других видов ошибок.

Один из примеров, где используются коды выхода, - в сценариях оболочки. В bash вы можете проверить специальную переменную $?для последнего статуса выхода:

me@mini:~$ python -c ""; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(0)"; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(43)"; echo $?
43

Лично я пытаюсь использовать коды выхода, которые я нахожу /usr/include/asm-generic/errno.h(в системе Linux), но я не знаю, правильно ли это делать.


3
Из другого поста я нашел эту ссылку: tldp.org/LDP/abs/html/exitcodes.html Может быть полезным. :)
Eigir

9
errno.h обычно для кодов выхода вызова функции. Попытки стандартизировать коды завершения программы привели к тому, что /usr/include/sysexits.h присутствует в большинстве систем POSIX.
mpounsett

1
Очень хорошо знать, что «программы Unix обычно используют 2 для ошибок синтаксиса командной строки»!
Дантистон

2
@ Dantiston Concur . Безжалостный адвокат Gentoo, крашеный в шерсти, но я никогда не знал этого ... до этого судьбоносного дня. ( Мой позор заканчивается сейчас. ) Кроме того, обратите внимание, что grepнарушает эту тенденцию, выходя с, 1когда ни одна строка не совпадает и 2на реальных ошибках. Большое спасибо, Столлман.
Сесил Карри

32

Для записи вы можете использовать стандартные коды выхода POSIX, определенные здесь .

Пример:

import sys, os

try:
    config()
except:
    sys.exit(os.EX_CONFIG) 
try:
    do_stuff()
except:
    sys.exit(os.EX_SOFTWARE)
sys.exit(os.EX_OK) # code 0, all ok

3
Согласно документам они доступны только в операционных системах Unix, поэтому они не полностью переносимы.
Феникс

1
Если вам нужны переносимые коды POSIX, доступные во всех операционных системах, см. exitstatusПакет PyPI.
Феникс

1
Полный пакет составляет 0 для успеха и 1 для отказа.
Павел Минаев

25

Есть errnoмодуль, который определяет стандартные коды выхода:

Например, « Отказано в доступе» - это код ошибки 13 :

import errno, sys

if can_access_resource():
    do_something()
else:
    sys.exit(errno.EACCES)

36
Это неверно Эти ошибки не предназначены для использования в качестве кодов завершения процесса. Это низкоуровневые коды ошибок, предназначенные для внутреннего использования в программах, особенно написанных на языке Си. Для Python используйте исключения, когда это возможно.
SvdB

2
Ты прав. Они должны быть использованы внутри. Но вы обычно не вызываете исключения на уровне конечного пользователя. Вы используете sys.exit (x), где x является целым числом, которое вы выбираете произвольно. Но вы можете использовать те, которые начинаются с EX_ и определены в модуле 'os'. Как os.EX_OK или os.EX_IOERR
Оли

2
Извините, но я также проголосую против, потому что это вводит в заблуждение. Коды состояния выхода и номера ошибок не являются взаимозаменяемыми / дополняющими. В данном примере «отказано в разрешении» имеет код ошибки 13 (согласно errnoи errno.h ), но код состояния выхода 77 (согласно osи sysexits.h ). Программы, которые испускают первое, являются нестандартными ( де-факто vel jure ) и не будут хорошо работать с другими, которые по праву ожидают второе.
Марк Г.

14

Коды выхода 0 обычно означают «здесь все в порядке». Однако, если программист сценария не следовал соглашению, вам, возможно, придется обратиться к источнику, чтобы понять, что это значит. Обычно ненулевое значение возвращается как код ошибки.


6

Ответ: «Зависит от того, что означает код выхода ноль»

Тем не менее, в большинстве случаев это означает, что «все в порядке»


Мне нравится POSIX:

Итак, на оболочке я бы набрал:

python script.py && echo 'OK' || echo 'Not OK'

Если мой скрипт Python вызывает, sys.exit(0)оболочка возвращает «ОК»

Если мой скрипт Python вызывает sys.exit(1)(или любое ненулевое целое число), оболочка возвращает «Не в порядке»

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


Просто для полноты, «Not OK» будет напечатано, если скрипт Python выдал ошибку ИЛИ имел синтаксическую ошибку.
Шиталь Шах

5

Команды операционной системы имеют коды выхода. Ищите коды выхода Linux, чтобы увидеть некоторые материалы по этому вопросу. Оболочка использует коды выхода, чтобы определить, сработала ли программа, возникли проблемы или произошла ошибка. Прилагаются некоторые усилия для создания стандартных (или, по крайней мере, обычно используемых) кодов выхода. Посмотрите эту публикацию Advanced Shell Script .


5

Я рекомендую чистое завершение с помощью встроенной функции exit (0), а не sys.exit ()

Я не уверен, если это хороший совет.

Сама упомянутая документация гласит:

Модуль сайта (который импортируется автоматически во время запуска, за исключением случаев, когда указана опция командной строки -S) добавляет несколько констант во встроенное пространство имен. Они полезны для оболочки интерактивного интерпретатора и не должны использоваться в программах .

Затем:

Выход (код = нет)

Объекты, которые при печати печатают сообщение типа «Используйте quit () или Ctrl-D (т.е. EOF) для выхода», а при вызове вызываете SystemExit с указанным кодом выхода.

Если мы сравним его с документацией sys.exit () , он использует тот же механизм, который вызывает SystemExitисключение.



4

Коды выхода имеют только значение, назначенное автором сценария. Традиция Unix такова, что код выхода 0 означает «успех», а все остальное - неудача. Единственный способ убедиться, что означают коды выхода для данного сценария, - изучить сам сценарий.


2

Коды выхода на многих языках программирования до программистов. Таким образом, вы должны посмотреть на исходный код вашей программы (или руководство). Ноль обычно означает «все прошло хорошо».



-2

Чтобы разрешить выполнение обработчиков исключений и других вещей, я рекомендую чистое завершение с помощью exit(0)встроенной функции, а не использование, sys.exit()которое резко завершает процесс.


Так в чем же разница? Откуда эта информация? Вы имеете в виду выполнение обработчиков "на выходе" или на что именно вы ссылаетесь? SystemExitПохоже, что так или иначе поднимается.
0xC0000022L

мм, я перепутал это с os._exitобоими, кажется, поднять SystemExit.
Виджет

1
Неправильно: sys.exit() делает выключение чисто, как exit(). Они оба делают одно и то же : создают SystemExitисключение. На самом деле, exit()предназначен для интерактивных сессий, а не сценариев, так что концептуально sys.exit() это указано. Вы можете быть смущены os._exit(), это тот, который заканчивается внезапно.
МестреЛион
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.