Вихід з кодів у Python


207

Я отримав повідомлення про те script xyz.py returned exit code 0. Що це означає?

Що означають вихідні коди в Python? Скільки їх? Які з них важливі?


1
Де ви бачите це повідомлення?
Джеремі Кантрелл

1
@Jeremy Внизу 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 Можливо, це буде корисним. :)
Егір

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
Це неправильно. Ці errno не призначені для використання в якості кодів виходу з процесу. Це коди помилок низького рівня, призначені для внутрішнього використання в програмах, зокрема, написаних мовою С. Для Python, використовуйте винятки, коли це можливо.
SvdB

2
Ти маєш рацію. Вони повинні використовуватися всередині країни. Але ви зазвичай не збільшуєте винятки на рівні кінцевого користувача. Ви використовуєте sys.exit (x), при цьому х є цілим числом, яке ви вибираєте довільно. Але ви можете використовувати ті, що починаються з EX_ та визначені в модулі 'os'. Як os.EX_OK або os.EX_IOERR
Олі,

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

14

Вихідні коди 0 зазвичай означають "тут нічого поганого". Однак якщо програміст сценарію не дотримувався конвенції, вам, можливо, доведеться звернутися до джерела, щоб побачити, що це означає. Зазвичай ненульове значення повертається як код помилки.


6

Відповідь «Залежить від того, що означає нульовий код виходу»

Однак у більшості випадків це означає "Все гаразд"


Мені подобається POSIX:

Отже, на оболонці я б набрав:

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

Якщо мій скрипт python викликає sys.exit(0)оболонку, повертається "ОК"

Якщо мій скрипт python викликає sys.exit(1)(або будь-яке ненульове ціле число), оболонка повертає "Не в порядку"

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


Просто для повноти буде надруковано "Не в порядку", якщо помилка піднятого сценарію Python АБО помилка синтаксису.
Shital Shah

5

Команди операційної системи мають коди виходу. Шукайте коди виходу linux, щоб побачити деякі матеріали з цього приводу. Оболонка використовує вихідні коди, щоб вирішити, чи працювала програма, мали проблеми чи не працювали. Докладаються певні зусилля для створення стандартних (або принаймні часто використовуваних) кодів виходу. Дивіться цю розширену публікацію сценарію оболонки .


5

Я рекомендую чисте відключення з вбудованим виходом (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.
vidstige

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