¿Existen códigos de estado de salida estándar en Linux?
Se considera que un proceso se completó correctamente en Linux si su estado de salida era 0.
He visto que las fallas de segmentación a menudo resultan en un estado de salida de 11, aunque no sé si esto es simplemente la convención donde trabajo (las aplicaciones que fallaron así fueron todas internas) o un estándar.
¿Existen códigos de salida estándar para procesos en Linux?
Parte 1: Guía avanzada de secuencias de comandos Bash
Como siempre, la Guía avanzada de secuencias de comandos Bash tiene excelente información : (Esto se vinculó en otra respuesta, pero a una URL no canónica).
1: Comodidad para errores generales
2: Uso indebido de las funciones integradas del shell (según la documentación de Bash)
126: El comando invocado no se puede ejecutar
127: "comando no encontrado"
128: Argumento no válido para salir
128+n: Señal de error grave "n"
255: Salir estado fuera de rango (la salida solo toma argumentos enteros en el rango 0 - 255)
Parte 2: sysexits.h
Las referencias ABSG sysexits.h
.
En Linux:
$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
(A whole bunch of text left out.)
#define EX_OK 0 /* successful termination */
#define EX__BASE 64 /* base value for error messages */
#define EX_USAGE 64 /* command line usage error */
#define EX_DATAERR 65 /* data format error */
#define EX_NOINPUT 66 /* cannot open input */
#define EX_NOUSER 67 /* addressee unknown */
#define EX_NOHOST 68 /* host name unknown */
#define EX_UNAVAILABLE 69 /* service unavailable */
#define EX_SOFTWARE 70 /* internal software error */
#define EX_OSERR 71 /* system error (e.g., can't fork) */
#define EX_OSFILE 72 /* critical OS file missing */
#define EX_CANTCREAT 73 /* can't create (user) output file */
#define EX_IOERR 74 /* input/output error */
#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
#define EX_PROTOCOL 76 /* remote error in protocol */
#define EX_NOPERM 77 /* permission denied */
#define EX_CONFIG 78 /* configuration error */
#define EX__MAX 78 /* maximum listed value */
Ninguna de las respuestas anteriores describe correctamente el estado de salida 2. Al contrario de lo que afirman, el estado 2 es lo que las utilidades de línea de comando realmente devuelven cuando se llaman incorrectamente. (Sí, una respuesta puede tener nueve años, cientos de votos positivos y aun así estar equivocada).
Aquí está la convención de estado de salida real y antigua para la terminación normal, es decir, no por señal:
- Estado de salida 0: éxito
- Estado de salida 1: "fallo", según lo definido por el programa
- Estado de salida 2: error de uso de la línea de comando
Por ejemplo, diff
devuelve 0 si los archivos que compara son idénticos y 1 si difieren. Por convención de larga data, los programas Unix devuelven el estado de salida 2 cuando se les llama incorrectamente (opciones desconocidas, número incorrecto de argumentos, etc.). Por ejemplo, diff -N
o grep -Y
todos diff a b c
resultarán en $?
ser establecidos en 2. Esta es y ha sido la práctica desde el Los primeros días de Unix en la década de 1970.
La respuesta aceptada explica lo que sucede cuando una señal finaliza un comando. En resumen, la terminación debido a una señal no captada da como resultado un estado de salida 128+[<signal number>
. Por ejemplo, la terminación por SIGINT
( señal 2 ) da como resultado el estado de salida 130.
Notas
Varias respuestas definen el estado de salida 2 como "Uso indebido de funciones integradas de bash". Esto se aplica sólo cuando bash (o un script bash) sale con el estado 2. Considérelo un caso especial de error de uso incorrecto.
En
sysexits.h
, mencionado en la respuesta más popular , el estado de salidaEX_USAGE
("error de uso de la línea de comando") se define como 64. Pero esto no refleja la realidad: no conozco ninguna utilidad común de Unix que devuelva 64 en una invocación incorrecta (se aceptan ejemplos ). Una lectura cuidadosa del código fuente revela quesysexits.h
es una aspiración, más que un reflejo del uso real:* This include file attempts to categorize possible error * exit statuses for system programs, notably delivermail * and the Berkeley network. * Error numbers begin at EX__BASE [64] to reduce the possibility of * clashing with other exit statuses that random programs may * already return.
En otras palabras, estas definiciones no reflejan la práctica común en ese momento (1993), sino que eran intencionalmente incompatibles con ella. Más es la lástima.
8 bits del código de retorno y 8 bits del número de la señal de eliminación se mezclan en un solo valor en el retorno de wait(2)
& co. .
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
int main() {
int status;
pid_t child = fork();
if (child <= 0)
exit(42);
waitpid(child, &status, 0);
if (WIFEXITED(status))
printf("first child exited with %u\n", WEXITSTATUS(status));
/* prints: "first child exited with 42" */
child = fork();
if (child <= 0)
kill(getpid(), SIGSEGV);
waitpid(child, &status, 0);
if (WIFSIGNALED(status))
printf("second child died with %u\n", WTERMSIG(status));
/* prints: "second child died with 11" */
}
¿Cómo se determina el estado de salida? Tradicionalmente, el shell sólo almacena un código de retorno de 8 bits, pero establece el bit alto si el proceso finalizó de forma anormal.
$ sh -c 'salida 42'; eco $? 42 $ sh -c 'matar -SEGV $$'; eco $? Fallo de segmentación 139 $ expr 139 - 128 11
Si ve algo más que esto, entonces el programa probablemente tenga un SIGSEGV
controlador de señal que luego llama exit
normalmente, por lo que la señal no lo elimina. (Los programas pueden optar por manejar cualquier señal además de SIGKILL
y SIGSTOP
).
'1' : Comodín para errores generales
'2' : Uso indebido de las funciones integradas del shell (según la documentación de Bash)
'126' : El comando invocado no se puede ejecutar
'127' : "comando no encontrado"
'128' : Argumento no válido para salir
'128+n' : Señal de error fatal "n"
'130' : Script terminado por Ctrl+C
'255' : Estado de salida fuera de rango
Esto es para Bash. Sin embargo, para otras aplicaciones, existen diferentes códigos de salida.