GNU/Linux >> Tutoriales Linux >  >> Linux

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

'1' :Catch-all para errores generales

'2' :Mal uso de las funciones internas de shell (según la documentación de Bash)

'126' :El comando invocado no puede ejecutarse

'127' :"comando no encontrado"

'128' :Argumento invá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.


Parte 1:Guía avanzada de secuencias de comandos de Bash

Como siempre, la Guía avanzada de secuencias de comandos de Bash tiene excelente información:(Esto se vinculó en otra respuesta, pero a una URL no canónica).

1: Catchall para errores generales
2: Mal uso de shell incorporados (según la documentación de Bash)
126: El comando invocado no puede ejecutarse
127: "Comando no encontrado"
128: Argumento inválido para salir
128+n: Señal de error fatal "n"
255: Estado de salida fuera de rango (la salida solo toma argumentos enteros en el rango de 0 a 255)

Parte 2:sysexits.h

El ABSG hace referencia a 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 */

8 bits del código de retorno y 8 bits del número de la señal de muerte 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 está 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 finaliza de manera anormal.

$ sh -c 'exit 42'; echo $?
42
$ sh -c 'kill -SEGV $$'; echo $?
Segmentation fault
139
$ expr 139 - 128
11

Si ve algo diferente a esto, entonces el programa probablemente tiene un SIGSEGV manejador de señales que luego llama a exit normalmente, por lo que en realidad no está siendo asesinado por la señal. (Los programas pueden elegir manejar cualquier señal aparte de SIGKILL y SIGSTOP .)


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 la línea de comandos realmente devuelven cuando se las llama incorrectamente. (Sí, una respuesta puede tener nueve años, tener cientos de votos a favor y seguir siendo incorrecta).

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:

  • 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 comandos

Por ejemplo, diff devuelve 0 si los archivos que compara son idénticos y 1 si son diferentes. Por convención de larga data, los programas de Unix devuelven estado de salida 2 cuando se les llama incorrectamente (opciones desconocidas, número incorrecto de argumentos, etc.) Por ejemplo, diff -N , grep -Y o diff a b c todo resultará en $? se establece en 2. Esta es y ha sido la práctica desde los primeros días de Unix en la década de 1970.

La respuesta aceptada explica qué sucede cuando un comando es terminado por 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, 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 bash incorporado". Esto se aplica solo 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, estado de salida EX_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 devuelve 64 en invocación incorrecta (ejemplos bienvenidos). Una lectura cuidadosa del código fuente revela que sysexits.h es una aspiración, en lugar de 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), pero fueron intencionalmente incompatibles con ella. Más es la lástima.


Linux
  1. ¿Hay alguna forma de obtener time_t de 64 bits en programas de 32 bits en Linux?

  2. ¿Hay alguna opción para permitir que cat salga con color?

  3. ¿Existen distribuciones modernas de Linux que aún sean compatibles con /dev/audio?

  4. ¿Hay alguna GUI para Linux que no use X11?

  5. ¿Hay alguna (buena) GUI de SQLite para Linux?

Linux:¿los valores mínimo y máximo de los códigos de salida en Linux?

Con Fedora 36, ​​podría haber un nuevo estándar de oro para las distribuciones de Linux

¿Hay algún equivalente de WinSCP para Linux?

¿Hay alguna API de C para extraer el nombre del archivo base de su ruta completa en Linux?

¿Por qué hay tantos /dev/tty en Linux?

¿Hay alguna forma de bloquear LD_PRELOAD y LD_LIBRARY_PATH en Linux?