Códigos de salida en Python

207

Recibí un mensaje que decía script xyz.py returned exit code 0. ¿Qué significa esto?

¿Qué significan los códigos de salida en Python? ¿Cuántos hay? ¿Cuáles son importantes?

sol profundo
fuente
1
¿Dónde ves este mensaje?
Jeremy Cantrell
1
@ Jeremy En la parte inferior de PythonWin.
Sundeep

Respuestas:

223

Lo que estás buscando en el script son las llamadas a sys.exit(). El argumento de ese método se devuelve al entorno como el código de salida.

Es bastante probable que el script nunca llame al método de salida, y que 0 es el código de salida predeterminado.

Dave Costa
fuente
12
No estoy seguro en absoluto. En Unix / Linux, el estándar es: salir 0 en caso de que todo estuviera bien. Escriba un comando, luego echo $ ?: si lee 0, se devuelve sin error. La idea es tener pruebas estándar. Si el código xyz.py no encontró ningún error, ¡DEBERÍA devolver 0!
Bruno von Paris
1
Si desea cambiar el código de salida, prefiera salir limpiamente usando la salida incorporada, vea esta respuesta
vidstige
101

De la documentación parasys.exit :

El argumento opcional arg puede ser un número entero que proporciona el estado de salida (predeterminado a cero) u otro tipo de objeto. Si es un número entero, cero se considera "terminación exitosa" y cualquier valor distinto de cero se considera "terminación anormal" por shells y similares. La mayoría de los sistemas requieren que esté en el rango de 0 a 127 y, de lo contrario, producen resultados indefinidos. Algunos sistemas tienen una convención para asignar significados específicos a códigos de salida específicos, pero estos generalmente están subdesarrollados; Los programas Unix generalmente usan 2 para errores de sintaxis de línea de comando y 1 para todos los demás tipos de errores.

Un ejemplo donde se usan códigos de salida son los scripts de shell. En bash puede verificar la variable especial $?para el último estado de salida:

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 trato de usar los códigos de salida que encuentro en /usr/include/asm-generic/errno.h(en un sistema Linux), pero no sé si esto es lo correcto.

Eigir
fuente
3
En otra publicación encontré este enlace: tldp.org/LDP/abs/html/exitcodes.html Podría ser útil. :)
Eigir
9
errno.h es típicamente para códigos de salida de llamada de función. Los intentos de estandarizar los códigos de salida del programa han resultado en /usr/include/sysexits.h presente en la mayoría de los sistemas POSIX.
mpounsett
1
¡Es muy bueno saber que "los programas de Unix generalmente usan 2 para errores de sintaxis de línea de comandos"!
dantiston
2
@dantiston Concur. Defensor de Gentoo teñido en la lana, pero nunca supe eso ... hasta este día predestinado. ( Mi vergüenza termina ahora ) . Relacionado, tenga en cuenta que greprompe esta tendencia al salir 1cuando no coinciden las líneas y 2en los errores reales. Muchas gracias, Stallman.
Cecil Curry
32

Para el registro, puede usar los códigos de salida estándar POSIX definidos aquí .

Ejemplo:

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
fuente
3
Según los documentos, estos solo están disponibles en los sistemas operativos Unix, por lo que no es totalmente portátil.
Phoenix
1
Si desea códigos POSIX portátiles disponibles en todos los sistemas operativos, consulte el exitstatuspaquete PyPI.
Phoenix
1
La totalidad de ese paquete es 0 para el éxito y 1 para el fracaso.
Pavel Minaev
25

Hay un errno módulo que define los códigos de salida estándar:

Por ejemplo, el permiso denegado es el código de error 13 :

import errno, sys

if can_access_resource():
    do_something()
else:
    sys.exit(errno.EACCES)
Oli
fuente
36
Esto es incorrecto. Estos errores no están destinados a ser utilizados como códigos de salida de proceso. Estos son códigos de error de bajo nivel destinados a ser utilizados internamente en programas, específicamente aquellos escritos en lenguaje C. Para Python, use excepciones siempre que sea posible.
SvdB
2
Tienes razón. Estos deben ser utilizados internamente. Pero normalmente no genera excepciones en el nivel del usuario final. Utiliza sys.exit (x) con x siendo un número entero que elige arbitrariamente. Pero puede usar aquellos que comienzan con EX_ y se definen en el módulo 'os'. Como os.EX_OK o os.EX_IOERR
Oli
2
Lo siento, pero también estoy rechazando esto porque es engañoso. Los códigos de estado de salida y los números de error no son intercambiables / complementarios. Usando el ejemplo dado, "permiso denegado" tiene un código de error de 13 (según errnoy errno.h ), pero un código de estado de salida de 77 (según osy sysexits.h ). Los programas que emiten los primeros no son estándar ( de facto vel jure ) y no funcionarán bien con otros que con razón esperan lo último.
Mark G.
14

Los códigos de salida de 0 generalmente significan "aquí no hay nada malo". Sin embargo, si el programador del script no siguió la convención, es posible que deba consultar la fuente para ver qué significa. Por lo general, se devuelve un valor distinto de cero como un código de error.

Sam Corder
fuente
6

La respuesta es "Depende de lo que signifique el código de salida cero"

Sin embargo, en la mayoría de los casos, esto significa "Todo está bien"


Me gusta POSIX:

Entonces, en el shell, escribiría:

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

Si mi script de Python llama sys.exit(0) al shell, devuelve 'OK'

Si mi script de Python llama sys.exit(1) (o cualquier número entero distinto de cero), el shell devuelve 'No está bien'

Es su trabajo ser inteligente con el shell y leer la documentación (o la fuente) de su script para ver qué significan los códigos de salida.

FlipMcF
fuente
Solo para completar, se imprimirá 'No está bien' si el script de Python generó un error O tuvo un error de sintaxis.
Shital Shah
5

Los comandos del sistema operativo tienen códigos de salida. Busque códigos de salida de Linux para ver material sobre esto. El shell utiliza los códigos de salida para decidir si el programa funcionó, tuvo problemas o falló. Hay algunos esfuerzos para crear códigos de salida estándar (o al menos de uso común). Vea esta publicación de Advanced Shell Script .

S.Lott
fuente
5

Recomiendo un apagado limpio con la salida (0) incorporada en lugar de usar sys.exit ()

No estoy seguro si este es un buen consejo.

La misma documentación mencionada dice:

El módulo del sitio (que se importa automáticamente durante el inicio, excepto si se da la opción de línea de comandos -S) agrega varias constantes al espacio de nombres incorporado. Son útiles para el intérprete interactivo y no deben usarse en programas .

Luego:

salida (código = Ninguno)

Objetos que, cuando se imprimen, imprimen un mensaje como "Use quit () o Ctrl-D (es decir, EOF) para salir", y cuando se le llama, levanta SystemExit con el código de salida especificado.

Si lo comparamos con la documentación de sys.exit () , está utilizando el mismo mecanismo que está generando una SystemExitexcepción.

debilucho
fuente
5

Si desea utilizar de forma portátil los códigos de salida POSIX estándar , consulte el exitstatuspaquete en PyPI.

Instala el paquete:

$ pip install exitstatus

Use en su código:

import sys
from exitstatus import ExitStatus

sys.exit(ExitStatus.success)
fénix
fuente
4

Los códigos de salida solo tienen el significado asignado por el autor del script. La tradición de Unix es que el código de salida 0 significa 'éxito', cualquier otra cosa es fracaso. La única forma de asegurarse de lo que significan los códigos de salida para un script determinado es examinar el script en sí.

Harper Shelby
fuente
2

Los códigos de salida en muchos lenguajes de programación dependen de los programadores. Por lo tanto, debe mirar el código fuente de su programa (o manual). Cero generalmente significa "todo salió bien".

Davide
fuente
0

Siguiendo los códigos de salida de Unix 0 - para éxito / OK, 1 - sin éxito / error. Simplemente puede usar exit(0)o exit(1)llamar sin importar el sysmódulo.

Lukasz Dynowski
fuente
-2

Para permitir que se ejecuten controladores de excepciones y otras cosas, recomiendo un apagado limpio con el exit(0)incorporado en lugar de usar el sys.exit()que finaliza el proceso abruptamente.

vidstige
fuente
Entonces, ¿cuál es la diferencia? ¿De dónde viene esta información? ¿Te refieres a la ejecución de los controladores "a la salida" o a qué te refieres exactamente? SystemExitparece levantarse de cualquier manera.
0xC0000022L
mm, lo confundí con os._exit, ambos parecen subir SystemExit.
vidstige
1
Incorrecto: sys.exit() se apaga limpiamente, al igual que exit(). Ambos hacen lo mismo : plantear una SystemExitexcepción. En realidad, exit()está destinado a las sesiones interactivas, no a los scripts, por lo que conceptualmente sys.exit() es el indicado. Puede ser confuso con os._exit(), ese es el que termina abruptamente.
MestreLion