¿Existen códigos de estado de salida estándar en Linux?

Resuelto Nathan Fellman asked hace 15 años • 12 respuestas

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?

Nathan Fellman avatar Jul 09 '09 12:07 Nathan Fellman
Aceptado

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 */
Schof avatar Oct 08 '2009 05:10 Schof

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, diffdevuelve 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 -No grep -Ytodos diff a b cresultará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

  1. 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.

  2. En sysexits.h, mencionado en la respuesta más popular , el estado de salida EX_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 que sysexits.hes 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 oth­er 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.

alexis avatar Nov 08 '2016 10:11 alexis

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 SIGSEGVcontrolador de señal que luego llama exitnormalmente, por lo que la señal no lo elimina. (Los programas pueden optar por manejar cualquier señal además de SIGKILLy SIGSTOP).

ephemient avatar Jul 09 '2009 15:07 ephemient

'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.

segfault avatar Jul 09 '2009 05:07 segfault