También disponible en: English · Português · Français · العربية
Códigos de salida explicados
Consulta un código de salida de Unix y mira todas las lecturas que admite, y qué documento respalda cada una.
Qué es un código de salida
Cuando un programa termina, entrega al sistema un solo número entre 0 y 255. Cero significa que salió bien. Cualquier otra cosa significa que no, y eso es casi todo lo que está garantizado. El shell guarda ese número en la variable que se escribe con un signo de interrogación, los sistemas de integración continua lo imprimen cuando falla un paso, y los runtimes de contenedores lo informan cuando algo se detiene.
Casi todas las tablas de códigos de salida de la web presentan una única lista plana —0 éxito, 1 error general, 2 mal uso de builtins, del 64 al 78 de sysexits, 126, 127, 128 más el número de señal— como si un solo estándar dijera todo eso. Al leer los documentos de verdad, esas filas vienen de cuatro sitios distintos, y una de las más citadas no viene de ninguno. Esta página descodifica un código y te dice, para cada lectura, qué documento la respalda.
La distinción no es quisquillosa. Es la diferencia entre una regla que puedes esperar que otro programa cumpla y una costumbre que resulta ser habitual en el rincón del mundo donde la aprendiste.
Cómo se usa
- Escribe el número. El que te haya dado tu log de CI, tu runtime de contenedores o tu shell. Los botones cubren los que más aparecen.
- Lee todas las lecturas, no solo la primera. Un mismo número puede ser varias cosas a la vez: 64 es tanto un código de sysexits como un número cualquiera que un programa eligió por sus propios motivos, y enseñar solo una de las dos sería afirmar algo que las fuentes no sostienen.
- Fíjate en quién lo define. Cada lectura viene etiquetada como POSIX, manual de Bash, sysexits.h o ningún estándar. Esa etiqueta es la parte que conviene recordar.
Qué números están realmente especificados
POSIX, en su capítulo sobre el lenguaje del shell, fija muy poco: cero para el éxito, 127 cuando no se encuentra un comando y 126 cuando se encuentra pero no se puede ejecutar. Esos tres se pueden dar por buenos en cualquier parte. Para un programa matado por una señal solo dice que el código será mayor que 128 y que identificará la señal de una manera definida por la implementación; no dice 128 más el número de señal.
Esa última parte sorprende, porque 128 más el número de señal es exactamente lo que ocurre. Está en el manual de Bash y no en POSIX: bash declara que cuando un comando termina por una señal fatal N usa 128+N. Medido aquí con bash, dash y el shell del sistema, los tres coincidieron: un proceso matado por SIGTERM devolvió 143, por SIGKILL 137, por SIGINT 130 y por SIGHUP 129. Es de fiar en la práctica, y es la promesa de un shell, no la del estándar.
Bash también define el 2, pero de forma mucho más estrecha de lo que sugieren las tablas: todos sus builtins devuelven 2 para indicar un uso incorrecto, como una opción inválida o un argumento que falta. Eso es un hecho sobre los builtins de bash. No es un consejo sobre lo que debería devolver tu script, y nada obliga a ningún otro programa a seguirlo.
Y luego está el 1, el código de salida más tabulado de internet, rotulado en todas partes como error general. Ningún documento lo define. POSIX y el manual de Bash dicen únicamente que un valor distinto de cero indica fallo. Contando los 256 valores posibles, algún documento dice algo sobre 50 de ellos; los otros 206 quedan enteramente a criterio del programa.
Dos cosas que las tablas cuentan mal
La primera es sysexits. Los códigos del 64 al 78 se presentan en todas partes como los códigos de salida estándar, y nunca formaron parte de POSIX. Vienen de una cabecera de C escrita para sendmail, y la cabecera es llamativamente franca consigo misma: dice que los valores existen solo por compatibilidad de interfaz y están obsoletos para el software base de FreeBSD, que se escribieron para sendmail en particular y —justo antes de enumerarlos— que el significado de los códigos es aproximadamente el siguiente. Un conjunto de constantes cuyo propio autor califica sus significados de aproximados es una convención razonable dentro de un proyecto que ya la usa, y una mala apuesta si esperas que el programa de un desconocido la respete.
La segunda es que 128 más un número de señal no siempre identifica una señal. Para volver del código a la señal hay que saber qué señal lleva ese número, y los números de señal no son iguales en todas partes. En Linux sobre x86 la señal 10 es SIGUSR1; en Alpha, SPARC y macOS es SIGBUS. Así que el código 138 significa una señal de usuario en una máquina y un error de bus en otra, y ninguna tabla que imprima un solo nombre puede acertar en ambas. Escribe 138 arriba y la herramienta te enseña la división en vez de elegir por ti.
Hay una trampa menor en el otro sentido. El código son ocho bits, así que devolver algo mayor da la vuelta en silencio: exit 256 llega como 0, lo que convierte un fallo en un éxito. Medido aquí, exit 300 volvió como 44 y exit 257 como 1. Los negativos son peores que un simple desbordamiento: bash convirtió -1 en 255, mientras que dash lo rechazó con un mensaje de número ilegal y devolvió 2, de modo que el mismo script informa de dos fallos distintos según qué shell lo ejecute.
Por qué distinto de cero no significa roto
La convención que todos llevamos encima es que cero está bien y cualquier otra cosa es un problema. Las dos utilidades que más aparecen en una tubería la contradicen. grep devuelve 1 cuando sencillamente no encontró coincidencias, y reserva el 2 para un error de verdad. diff devuelve 1 cuando los archivos difieren, que es la respuesta normal a la pregunta que le hiciste, y también reserva el 2. cmp hace lo mismo.
Esta es la razón práctica de que importe la advertencia que aparece al final de cada resultado de esta página. Un script con set -e se detendrá ante un grep que no encontró nada, porque el shell no puede distinguir entre una respuesta negativa y un fallo: ambas son 1. Saber cuáles de tus herramientas usan el 1 como respuesta y no como error es más útil que cualquier tabla de códigos estándar, porque es el caso que de verdad muerde.
Si estás eligiendo códigos para tu propio programa: cero para el éxito, distinto de cero para el fallo, y documenta qué significa cada número. Ese es todo el contrato portable. Si quieres más estructura, elige un esquema y escríbelo, porque quien lea tu código de salida no tiene forma de consultarlo.
¿Por qué es gratis?
Esto es una tabla de consulta y algo de aritmética, ejecutándose en tu navegador. No hay nada que correr en un servidor, así que no hay nada que cobrar ni cuenta que crear.
Nada de lo que escribes se sube, se guarda ni se registra, y tampoco habría mucho que registrar: la entrada es un número entre 0 y 255.