Se considera que un proceso se ha completado 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 esta es simplemente la convención en la que trabajo (las aplicaciones que fallaron así han sido internas) o un estándar.
¿Existen códigos de salida estándar para procesos en Linux?
linux
error-handling
exit-code
Nathan Fellman
fuente
fuente
Respuestas:
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. .¿Cómo estás determinando el estado de salida? Tradicionalmente, el shell solo almacena un código de retorno de 8 bits, pero establece el bit alto si el proceso finalizó de manera anormal.
Si ve algo más que esto, entonces el programa probablemente tenga un
SIGSEGV
controlador de señal que luego llamaexit
normalmente, por lo que la señal no lo mata. (Los programas pueden elegir manejar cualquier señal aparte deSIGKILL
ySIGSTOP
.)fuente
Parte 1: Guía avanzada de secuencias de comandos Bash
Como siempre, la Guía avanzada de secuencias de comandos de Bash tiene excelente información : (Esto estaba vinculado en otra respuesta, pero a una URL no canónica).
Parte 2: sysexits.h
Las referencias de ABSG
sysexits.h
.En Linux:
fuente
man sysexits
sysexits.h
? La página de manual que todo el mundo hace referencia es solo prosa. Por ejemplo, hace referencia,EX_OK
pero en realidad no lo define de una manera normativa como los otros códigos. ¿Hay más que faltan?'1' >>> Catchall para errores generales
'2' >>> Uso indebido de los componentes integrados de 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 Control-C
'255' >>> Estado de salida fuera de rango
Esto es para bash. Sin embargo, para otras aplicaciones, hay diferentes códigos de salida.
fuente
Ninguna de las respuestas anteriores describe el estado de salida 2 correctamente. Al contrario de lo que afirman, el estado 2 es lo que sus utilidades de línea de comando realmente devuelven cuando se les llama incorrectamente. (Sí, una respuesta puede tener nueve años, tener cientos de votos a favor y aún estar equivocado).
Aquí está la convención de estado de salida real y de larga data para la terminación normal, es decir, no por señal:
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 de Unix devuelven el estado de salida 2 cuando se los llama incorrectamente (opciones desconocidas, número incorrecto de argumentos, etc.) Por ejemplodiff -N
,grep -Y
odiff a b c
todo resultará en$?
establecerse en 2. Esta es y ha sido la práctica desde primeros días de Unix en la década de 1970.La respuesta aceptada explica qué sucede cuando un comando termina con una señal. En resumen, la terminación debido a una señal no detectada da como resultado el estado de salida
128+[<signal number>
. Por ejemplo, la terminación porSIGINT
( señal 2 ) da como resultado el estado de salida 130.Notas
Varias respuestas definen el estado de salida 2 como "Uso incorrecto de bash builtins". Esto se aplica solo cuando bash (o un script bash) sale con el estado 2. Considere 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 comandos") 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 ) La lectura cuidadosa del código fuente revela quesysexits.h
es aspiracional, más que un reflejo del uso verdadero:En otras palabras, estas definiciones no reflejan la práctica común en ese momento (1993) pero fueron intencionalmente incompatibles con ella. Más es la pena.
fuente
more
restablecerá los modos del terminal y saldrá con el estado 0 (puede probarlo).No hay códigos de salida estándar, aparte de 0 que significa éxito. No cero tampoco significa necesariamente un fracaso.
stdlib.h define
EXIT_FAILURE
como 1 yEXIT_SUCCESS
como 0, pero eso es todo.El 11 en segfault es interesante, ya que 11 es el número de señal que el kernel usa para matar el proceso en caso de un segfault. Es probable que haya algún mecanismo, ya sea en el núcleo o en el shell, que se traduzca en el código de salida.
fuente
sysexits.h tiene una lista de códigos de salida estándar. Parece que se remonta al menos a 1993 y algunos grandes proyectos como Postfix lo usan, así que imagino que es el camino a seguir.
Desde la página de manual de OpenBSD:
fuente
Para una primera aproximación, 0 es éxito, no cero es falla, siendo 1 una falla general y cualquier cosa mayor que uno es una falla específica. Aparte de las excepciones triviales de falso y prueba, que están diseñadas para dar 1 por éxito, encontré algunas otras excepciones.
De manera más realista, 0 significa éxito o tal vez falla, 1 significa falla general o tal vez éxito, 2 significa falla general si 1 y 0 se usan para el éxito, pero tal vez también el éxito.
El comando diff proporciona 0 si los archivos comparados son idénticos, 1 si difieren y 2 si los binarios son diferentes. 2 también significa fracaso. El comando less da 1 por falla a menos que no proporcione un argumento, en cuyo caso, sale de 0 a pesar de fallar.
El comando more y el comando de deletreo dan 1 por falla, a menos que la falla sea el resultado de un permiso denegado, un archivo inexistente o un intento de leer un directorio. En cualquiera de estos casos, salen de 0 a pesar de fallar.
Luego, el comando expr da 1 para el éxito a menos que la salida sea la cadena vacía o cero, en cuyo caso, 0 es el éxito. 2 y 3 son fracaso.
Luego hay casos en los que el éxito o el fracaso son ambiguos. Cuando grep no puede encontrar un patrón, sale 1, pero sale 2 por una falla genuina (como permiso denegado). Klist también sale 1 cuando no puede encontrar un ticket, aunque esto no es realmente un error mayor que cuando grep no encuentra un patrón o cuando es un directorio vacío.
Entonces, desafortunadamente, los poderes de Unix que parecen no imponen ningún conjunto lógico de reglas, incluso en ejecutables muy comúnmente utilizados.
fuente
Los programas devuelven un código de salida de 16 bits. Si el programa fue eliminado con una señal, entonces el byte de orden superior contiene la señal utilizada; de lo contrario, el byte de orden inferior es el estado de salida devuelto por el programador.
¿Cómo se asigna ese código de salida a la variable de estado $? entonces depende del caparazón. Bash mantiene los 7 bits inferiores del estado y luego usa 128 + (señal nr) para indicar una señal.
La única convención "estándar" para los programas es 0 para el éxito, no cero para el error. Otra convención utilizada es devolver errno en caso de error.
fuente
Los códigos de salida estándar de Unix están definidos por sysexits.h, como se menciona en otro póster. Las bibliotecas portátiles, como Poco, usan los mismos códigos de salida. Aquí hay una lista de ellos:
http://pocoproject.org/docs/Poco.Util.Application.html#16218
Una señal 11 es una señal SIGSEGV (violación de segmento), que es diferente de un código de retorno. Esta señal es generada por el núcleo en respuesta a un mal acceso a la página, lo que hace que el programa finalice. Puede encontrar una lista de señales en la página de manual de señales (ejecute "señal de hombre").
fuente
Cuando Linux devuelve 0, significa éxito. Cualquier otra cosa significa falla, cada programa tiene sus propios códigos de salida, ¡así que sería bastante largo enumerarlos a todos ...!
Acerca del código de error 11, de hecho es el número de falla de segmentación, lo que significa que el programa accedió a una ubicación de memoria que no fue asignada.
fuente