GNU/Linux >> Tutoriales Linux >  >> Linux

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

¿Cuáles son los valores mínimo y máximo de los siguientes códigos de salida en Linux:

  1. El código de salida devuelto por un ejecutable binario (por ejemplo:un programa C
    ).
  2. El código de salida devuelto por un script bash (al llamar a exit ).
  3. El código de salida devuelto por una función (al llamar a return ). Yo
    creo que esto es entre y 255 .

Respuesta aceptada:

El número pasado al _exit() /exit_group() llamada al sistema (a veces denominada código de salida) para evitar la ambigüedad con estado de salida que también se refiere a una codificación del código de salida o del número de señal e información adicional dependiendo de si el proceso se eliminó o se cerró normalmente) es del tipo int , por lo que en sistemas similares a Unix como Linux, generalmente un número entero de 32 bits con valores de -2147483648 (-2) a 2147483647 (2-1).

Sin embargo, en todos los sistemas, cuando el proceso principal (o el secundario secundario o init si el padre murió) usa wait() , waitpid() , wait3() , wait4() llamadas del sistema para recuperarlo, solo los 8 bits inferiores están disponibles (valores de 0 a 255 (2-1)).

Cuando se usa waitid() API (o un controlador de señal en SIGCHLD), en la mayoría de los sistemas (y como POSIX ahora requiere más claramente en la edición 2016 del estándar (ver _exit() especificación)), el número completo está disponible (en el si_status campo de la estructura devuelta). Sin embargo, ese no es el caso en Linux, que también trunca el número a 8 bits con waitid() API, aunque es probable que eso cambie en el futuro.

En general, solo querrá usar valores de 0 (generalmente significa éxito) a 125 solo, ya que muchos shells usan valores superiores a 128 en su $? representación del estado de salida para codificar el número de señal de un proceso que se está matando y 126 y 127 para condiciones especiales.

Es posible que desee utilizar 126 a 255 en exit() para significar lo mismo que para el $? del shell (como cuando un script hace ret=$?; ...; exit "$ret" ). El uso de valores fuera de 0 -> 255 generalmente no es útil. Por lo general, solo haría eso si sabe que el padre usará el waitid() API en sistemas que no se truncan y necesita el rango de valores de 32 bits. Tenga en cuenta que si hace un exit(2048) por ejemplo, eso será visto como un éxito por los padres que usan el tradicional wait*() API.

Más información en:

  • ¿Código de salida predeterminado cuando finaliza el proceso?

Con suerte, esas preguntas y respuestas deberían responder a la mayoría de sus otras preguntas y aclarar qué significa estado de salida . Agregaré algunas cosas más:

Un proceso no puede terminar a menos que se elimine o llame al _exit() /exit_group() llamadas del sistema. Cuando regresas de main() en C , la libc llama a esa llamada del sistema con el valor devuelto.

La mayoría de los idiomas tienen un exit() función que envuelve esa llamada al sistema, y ​​el valor que toman, si alguno, generalmente se pasa tal cual a la llamada al sistema. (tenga en cuenta que generalmente hacen más cosas como la limpieza realizada por exit() de C función que vacía los búferes de stdio, ejecuta atexit() ganchos…)

Relacionado:Linux – ¿Cómo reutilizar Ubuntu APT?

Ese es el caso de al menos:

$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234)                        = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234)                        = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234)                        = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)

De vez en cuando ves algunos que se quejan cuando usas un valor fuera de 0-255:

$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1)                           = ?

Algunas conchas se quejan cuando usas un valor negativo:

$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2)                           = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2)                           = ?

POSIX deja el comportamiento sin definir si el valor pasó a exit la función especial está fuera de 0->255.

Algunos proyectiles muestran comportamientos inesperados si lo hace:

  • bash (y mksh pero no pdksh en el que se basa) se encarga de truncar el valor a 8 bits:

    $ strace -e exit_group bash -c 'exit 1234'
    exit_group(210)                         = ?
    

    Entonces, en esos shells, si desea salir con un valor fuera de 0-255, debe hacer algo como:

    exec zsh -c 'exit -- -12345'
    exec perl -e 'exit(-12345)'
    

    Eso es ejecutar otro comando en el mismo proceso que puede llame a la llamada del sistema con el valor que desee.

  • como se mencionó en otras preguntas y respuestas, ksh93 tiene el comportamiento más extraño para los valores de salida de 257 a 256+max_signal_number donde en lugar de llamar a exit_group() , se suicida con la señal correspondiente¹.

    $ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    zsh: suspended (signal)  ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    

    y de lo contrario trunca el número como bash /mksh .


Linux
  1. Ver comandos y tareas con el comando watch de Linux

  2. Introducción a los comandos chgrp y newgrp de Linux

  3. Inodes y el sistema de archivos de Linux

  4. Encuentra los archivos y directorios más grandes en Linux

  5. ¿Alguna forma de saber el tamaño de L1, L2, L3 Cache y RAM en Linux?

¿Cuál es la diferencia entre Linux y Unix?

Las 5 mejores distribuciones de Linux para desarrolladores y programadores

Monitoreo y prueba de la salud de SSD en Linux

Cómo encontrar el PID y PPID de un proceso en Linux

Un tipo de Windows en un mundo Linux:YaST y el escritorio

Perf de Linux:cómo usar el comando y el generador de perfiles