Wyjdź z kodów w Pythonie

207

Dostałem wiadomość z informacją script xyz.py returned exit code 0. Co to znaczy?

Co oznaczają kody zakończenia w Pythonie? Ile tu tego jest? Które są ważne?

niedziela
źródło
1
Gdzie widzisz tę wiadomość?
Jeremy Cantrell,
1
@Jeremy Na dole PythonWin.
niedziela,

Odpowiedzi:

223

To, czego szukasz w skrypcie, to wywołania sys.exit(). Argument tej metody jest zwracany do środowiska jako kod wyjścia.

Jest całkiem prawdopodobne, że skrypt nigdy nie wywołuje metody wyjścia, a 0 jest domyślnym kodem wyjścia.

Dave Costa
źródło
12
Wcale nie jestem pewien. W systemach Unix / Linux standardem jest: wyjście 0 w przypadku, gdy wszystko jest w porządku. Wpisz polecenie, a następnie echo $ ?: jeśli czytasz 0, zwróciło ono bez błędu. Chodzi o to, aby mieć standardowe testy. Jeśli kod xyz.py nie napotkał żadnego błędu, POWINIEN zwrócić 0!
Bruno von Paris
1
Jeśli chcesz zmienić kod wyjścia, wolisz wyjść czysto za pomocą wbudowanego wyjścia, zobacz tę odpowiedź
vidstige
101

Z dokumentacji dlasys.exit :

Opcjonalnym argumentem arg może być liczba całkowita podająca status wyjścia (domyślnie zero) lub inny typ obiektu. Jeśli jest to liczba całkowita, zero jest uważane za „pomyślne zakończenie”, a każda niezerowa wartość jest uważana za „nienormalne zakończenie” przez powłoki i tym podobne. Większość systemów wymaga, aby znajdowała się w przedziale 0–127 i w przeciwnym razie dawałaby niezdefiniowane wyniki. Niektóre systemy mają konwencję nadawania określonych znaczeń określonym kodom wyjścia, ale są one na ogół słabo rozwinięte; Programy uniksowe zwykle używają 2 dla błędów składni wiersza poleceń i 1 dla wszystkich innych rodzajów błędów.

Jednym z przykładów użycia kodów wyjścia są skrypty powłoki. W bash możesz sprawdzić specjalną zmienną $?dla ostatniego statusu wyjścia:

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

Osobiście staram się używać kodów wyjścia, które znajduję /usr/include/asm-generic/errno.h(w systemie Linux), ale nie wiem, czy jest to właściwe.

Eigir
źródło
3
W innym poście znalazłem ten link: tldp.org/LDP/abs/html/exitcodes.html Może być użyteczny. :)
Eigir,
9
errno.h jest zwykle dla kodów wyjścia wywołania funkcji. Próby standaryzacji kodów wyjścia programu spowodowały, że /usr/include/sysexits.h był obecny w większości systemów POSIX.
mpounsett
1
Dobrze wiedzieć, że „programy uniksowe zwykle używają 2 do błędów składni wiersza poleceń”!
dantiston
2
@dantiston Concur. Twardy, barwiony na wełnę rzecznik Gentoo, ale nigdy nie wiedziałem o tym ... aż do tego przeznaczonego dnia. ( Mój wstyd kończy się teraz. ) Podobnie, zwróć uwagę, że grepprzerywa ten trend, wychodząc z 1kiedy żadne linie nie pasują i 2na faktycznych błędach. Wielkie dzięki, Stallman.
Cecil Curry
32

Dla przypomnienia możesz użyć zdefiniowanych tutaj standardowych kodów wyjścia POSIX .

Przykład:

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
Laffuste
źródło
3
Według dokumentacji są one dostępne tylko w systemach operacyjnych Unix, więc nie są w pełni przenośne.
feniks
1
Jeśli chcesz przenośne kody POSIX, które są dostępne we wszystkich systemach operacyjnych, zobacz exitstatuspakiet PyPI.
feniks
1
Całość tego pakietu wynosi 0 dla sukcesu, a 1 dla niepowodzenia.
Pavel Minaev
25

Istnieje errnomoduł definiujący standardowe kody wyjścia:

Na przykład odmowa dostępu to kod błędu 13 :

import errno, sys

if can_access_resource():
    do_something()
else:
    sys.exit(errno.EACCES)
Oli
źródło
36
To jest niepoprawne. Te errno nie są przeznaczone do użycia jako kody wyjścia procesu. Są to kody błędów niskiego poziomu przeznaczone do wewnętrznego użytku w programach, szczególnie tych napisanych w języku C. W przypadku Pythona używaj wyjątków, gdy tylko jest to możliwe.
SvdB,
2
Masz rację. Należy ich używać wewnętrznie. Ale zwykle nie zgłaszasz wyjątków na poziomie użytkownika końcowego. Używasz sys.exit (x), gdzie x jest liczbą całkowitą, którą wybierzesz dowolnie. Ale możesz użyć tych zaczynających się od EX_ i zdefiniowanych w module „os”. Jak os.EX_OK lub os.EX_IOERR
Oli
2
Przepraszam, ale głosuję również w dół, ponieważ jest to mylące. Kody statusu wyjścia i numery błędów nie wymienne / komplementarne. W podanym przykładzie „odmowa dostępu ” ma kod błędu 13 (zgodnie z errnoi errno.h ), ale kod statusu wyjścia 77 (zgodnie z osi sysexits.h ). Programy emitujące te pierwsze są niestandardowe ( de facto vel jure ) i nie będą się dobrze bawić z innymi, które słusznie oczekują tego drugiego.
Mark G.
14

Kody wyjścia 0 zwykle oznaczają „nic złego tutaj”. Jednak jeśli programista skryptu nie przestrzegał konwencji, być może będziesz musiał skonsultować się ze źródłem, aby zobaczyć, co to znaczy. Zwykle niezerowa wartość jest zwracana jako kod błędu.

Sam Corder
źródło
6

Odpowiedź brzmi „Zależy od tego, co oznacza kod zakończenia zero”

Jednak w większości przypadków oznacza to „Wszystko w porządku”


Lubię POSIX:

Tak więc w powłoce napisałbym:

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

Jeśli mój skrypt python wywołuje sys.exit(0)powłokę, zwraca „OK”

Jeśli mój skrypt w języku Python wywołuje sys.exit(1)(lub dowolną liczbę całkowitą niezerową), powłoka zwraca „Nie OK”

Twoim zadaniem jest opanowanie powłoki i przeczytanie dokumentacji (lub źródła) skryptu, aby zobaczyć, co oznaczają kody zakończenia.

FlipMcF
źródło
Dla kompletności napis „Nie OK” zostanie wydrukowany, jeśli skrypt Python zgłosił błąd LUB wystąpił błąd składniowy.
Shital Shah,
5

Komendy systemu operacyjnego mają kody wyjścia. Poszukaj kodów wyjścia Linux, aby zobaczyć na ten temat trochę materiału. Powłoka używa kodów wyjścia, aby zdecydować, czy program działał, miał problemy lub nie. Podejmowane są wysiłki w celu stworzenia standardowych (lub przynajmniej powszechnie używanych) kodów wyjścia. Zobacz ten post dotyczący zaawansowanego skryptu powłoki .

S.Lott
źródło
5

Polecam czyste zamknięcie z wbudowanym wyjściem (0) zamiast używania sys.exit ()

Nie jestem pewien, czy to dobra rada.

Już wspomniana dokumentacja brzmi:

Moduł serwisu (który jest importowany automatycznie podczas uruchamiania, z wyjątkiem sytuacji, gdy podano opcję wiersza polecenia -S) dodaje kilka stałych do wbudowanej przestrzeni nazw. Są one przydatne dla interaktywnej powłoki interpretera i nie powinny być używane w programach .

Następnie:

wyjście (kod = brak)

Obiekty, które po wydrukowaniu wydrukują komunikat „Użyj quit () lub Ctrl-D (tj. EOF), aby wyjść”, a po wywołaniu podnieś SystemExit z określonym kodem wyjścia.

Jeśli porównamy to z dokumentacją sys.exit () , używa tego samego mechanizmu, który zgłasza SystemExitwyjątek.

słabycamel
źródło
4

Kody wyjścia mają jedynie znaczenie przypisane przez autora skryptu. Tradycja uniksowa głosi, że kod wyjścia 0 oznacza „sukces”, wszystko inne to porażka. Jedynym sposobem, aby upewnić się, co oznaczają kody zakończenia dla danego skryptu, jest sprawdzenie samego skryptu.

Harper Shelby
źródło
2

Kody wyjścia w wielu językach programowania zależą od programistów. Musisz więc spojrzeć na kod źródłowy programu (lub instrukcję). Zero zwykle oznacza „wszystko poszło dobrze”.

Davide
źródło
-2

Aby umożliwić obsługę wyjątków i inne rzeczy, zalecam czyste zamknięcie z exit(0)wbudowanym zamiast używania tego, sys.exit()który przerywa proces nagle.

vidstige
źródło
Więc jaka jest różnica? Skąd pochodzą te informacje? Masz na myśli wykonanie procedur obsługi „przy wyjściu” lub do czego konkretnie masz na myśli? SystemExitwydaje się być podniesiony w obu kierunkach.
0xC0000022L,
mm, pomyliłem z tym os._exit, oba wydają się podnosić SystemExit.
vidstige
1
Źle: sys.exit() czy zamknięcie jest czyste, tak jak exit(). Obaj robią to samo : podnoszą SystemExitwyjątek. W rzeczywistości exit()jest przeznaczony do interaktywnych sesji, a nie skryptów, więc koncepcyjnie sys.exit() jest wskazany. Możesz się mylić z os._exit()tym, który nagle się kończy.
MestreLion,