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?


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.


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.


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

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)

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.


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.


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

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.



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.


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”.


-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.


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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.