Codici di uscita in Python


207

Ho ricevuto un messaggio che diceva script xyz.py returned exit code 0. Cosa significa questo?

Cosa significano i codici di uscita in Python? Quanti sono lì? Quali sono importanti?


1
Dove vedi questo messaggio?
Jeremy Cantrell,

1
@Jeremy Nella parte inferiore di PythonWin.
domenica

Risposte:


223

Quello che stai cercando nello script sono le chiamate a sys.exit(). L'argomento di quel metodo viene restituito all'ambiente come codice di uscita.

È abbastanza probabile che lo script non stia mai chiamando il metodo di uscita e che 0 sia il codice di uscita predefinito.


12
Non ne sono affatto sicuro. In Unix / Linux, lo standard è: exit 0 nel caso tutto fosse ok. Digita un comando, quindi echo $ ?: se leggi 0, viene restituito senza errori. L'idea è di avere test standard. Se il codice xyz.py non ha riscontrato alcun errore, DOVREBBE restituire 0!
Bruno von Paris,

1
Se desideri modificare il codice di uscita, preferisci uscire in modo pulito utilizzando l'uscita incorporata, vedi questa risposta
vidstige

101

Dalla documentazione persys.exit :

L'argomento facoltativo arg può essere un numero intero che fornisce lo stato di uscita (impostazione predefinita a zero) o un altro tipo di oggetto. Se è un numero intero, zero è considerato "terminazione riuscita" e qualsiasi valore diverso da zero è considerato "terminazione anomala" da shell e simili. La maggior parte dei sistemi richiede che sia compreso nell'intervallo 0-127 e che altrimenti produca risultati indefiniti. Alcuni sistemi hanno una convenzione per assegnare significati specifici a codici di uscita specifici, ma questi sono generalmente sottosviluppati; I programmi Unix usano generalmente 2 per gli errori di sintassi della riga di comando e 1 per tutti gli altri tipi di errori.

Un esempio in cui vengono utilizzati i codici di uscita sono gli script di shell. In bash puoi controllare la variabile speciale $?per l'ultimo stato di uscita:

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

Personalmente provo ad usare i codici di uscita che trovo /usr/include/asm-generic/errno.h(su un sistema Linux), ma non so se questa è la cosa giusta da fare.


3
Da un altro post ho trovato questo link: tldp.org/LDP/abs/html/exitcodes.html Potrebbe essere utile. :)
Eigir,

9
errno.h è in genere per i codici di uscita delle chiamate di funzione. I tentativi di standardizzare i codici di uscita del programma hanno fatto sì che /usr/include/sysexits.h fosse presente sulla maggior parte dei sistemi POSIX.
mpounsett,

1
È molto bello sapere che "i programmi Unix usano generalmente 2 per errori di sintassi della riga di comando"!
Dantiston,

2
@dantiston Concur. Difficile avvocato di Gentoo tinto nella lana, ma non l'ho mai saputo ... fino a questo giorno fatale. (La mia vergogna termina ora. ) Inoltre, nota che grepinterrompe questa tendenza uscendo con 1quando nessuna linea corrisponde e 2su errori reali. Grazie mille, Stallman.
Cecil Curry,

32

Per la cronaca, è possibile utilizzare i codici di uscita standard POSIX definiti qui .

Esempio:

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
Secondo i documenti questi sono disponibili solo sui sistemi operativi Unix, quindi non è completamente portatile.
phoenix,

1
Se desideri codici POSIX portatili disponibili su tutti i sistemi operativi, consulta il exitstatuspacchetto PyPI.
phoenix,

1
L'intero pacchetto è 0 per esito positivo e 1 per errore.
Pavel Minaev,

25

C'è un errnomodulo che definisce i codici di uscita standard:

Ad esempio, l' autorizzazione negata è il codice di errore 13 :

import errno, sys

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

36
Questo non è corretto Questi errno non devono essere usati come codici di uscita del processo. Si tratta di codici di errore di basso livello destinati ad essere utilizzati internamente nei programmi, in particolare quelli scritti in linguaggio C. Per Python, usa le eccezioni quando possibile.
SvdB,

2
Hai ragione. Questi devono essere utilizzati internamente. Ma normalmente non si generano eccezioni a livello di utente finale. Si utilizza sys.exit (x) con x che è un numero intero scelto arbitrariamente. Ma puoi usare quelli che iniziano con EX_ e definiti nel modulo 'os'. Come os.EX_OK o os.EX_IOERR
Oli,

2
Mi dispiace, ma sto anche votando a favore, perché è fuorviante. I codici di stato di uscita e i numeri di errore non sono intercambiabili / complementari. Usando l'esempio dato, "permesso negato" ha un codice di errore di 13 (secondo errnoe errno.h ), ma un codice di stato di uscita di 77 (secondo ose sysexits.h ). I programmi che emettono i primi non sono standard ( di fatto ) e non funzionano bene con gli altri che si aspettano giustamente i secondi.
Mark G.

14

I codici di uscita pari a 0 in genere significano "qui non c'è niente di sbagliato". Tuttavia, se il programmatore dello script non ha seguito la convenzione, potrebbe essere necessario consultare la fonte per vedere cosa significa. Di solito viene restituito un valore diverso da zero come codice di errore.


6

La risposta è "Dipende dal significato del codice di uscita zero"

Tuttavia, nella maggior parte dei casi, ciò significa "Tutto ok"


Mi piace POSIX:

Quindi, sulla shell, scriverei:

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

Se il mio script Python chiama sys.exit(0)la shell restituisce 'OK'

Se il mio script Python chiama sys.exit(1)(o qualsiasi numero intero diverso da zero), la shell restituisce 'Non OK'

Il tuo compito è diventare intelligente con la shell e leggere la documentazione (o l'origine) dello script per vedere cosa significano i codici di uscita.


Solo per completezza, 'Not OK' verrà stampato se lo script Python ha generato un errore O ha avuto un errore di sintassi.
Shital Shah,

5

I comandi del sistema operativo hanno codici di uscita. Cerca i codici di uscita di Linux per vedere del materiale su questo. La shell utilizza i codici di uscita per decidere se il programma ha funzionato, ha avuto problemi o non è riuscito. Ci sono alcuni sforzi per creare codici di uscita standard (o almeno comunemente usati). Vedi questo invio avanzato di script di shell .


5

Raccomando un arresto pulito con exit (0) incorporato anziché utilizzare sys.exit ()

Non sono sicuro che questo sia un buon consiglio.

La stessa documentazione citata recita:

Il modulo del sito (che viene importato automaticamente durante l'avvio, tranne se viene fornita l'opzione della riga di comando -S) aggiunge diverse costanti allo spazio dei nomi incorporato. Sono utili per la shell dell'interprete interattivo e non dovrebbero essere usati nei programmi .

Poi:

uscita (codice = None)

Oggetti che, una volta stampati, stampano un messaggio del tipo "Usa quit () o Ctrl-D (cioè EOF) per uscire" e, quando chiamato, sollevano SystemExit con il codice di uscita specificato.

Se lo confrontiamo con la documentazione di sys.exit () , utilizza lo stesso meccanismo che genera SystemExitun'eccezione.


5

Se si desidera utilizzare in modo portabile i codici di uscita POSIX standard , consultare il exitstatuspacchetto su PyPI.

Installa il pacchetto:

$ pip install exitstatus

Usa nel tuo codice:

import sys
from exitstatus import ExitStatus

sys.exit(ExitStatus.success)

4

I codici di uscita hanno significato solo come assegnati dall'autore dello script. La tradizione Unix è che il codice di uscita 0 significa "successo", qualsiasi altra cosa è un fallimento. L'unico modo per essere sicuri del significato dei codici di uscita per un determinato script è esaminare lo script stesso.


2

I codici di uscita in molti linguaggi di programmazione sono a carico dei programmatori. Quindi devi guardare il codice sorgente del tuo programma (o manuale). Zero di solito significa "tutto è andato bene".



-2

Per consentire l'esecuzione di gestori di eccezioni e altre cose, raccomando un arresto pulito con l' exit(0)integrato anziché utilizzare il sys.exit()quale interrompe bruscamente il processo.


Quindi qual è la differenza? Da dove viene questa informazione? Intendi l'esecuzione dei gestori "all'uscita" o a cosa ti riferisci esattamente? SystemExitsembra essere sollevato in entrambi i modi.
0xC0000022L

mm, l'ho confuso os._exit, entrambi sembrano alzare SystemExit.
vidstige,

1
Sbagliato: sys.exit() fa l' arresto in modo pulito, proprio come exit(). Entrambi fanno la stessa cosa: sollevare SystemExitun'eccezione. In realtà, exit()è pensato per le sessioni interattive, non per gli script, quindi concettualmente sys.exit() è quello indicato. Potresti essere confuso os._exit(), è quello che termina bruscamente.
MestreLion,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.