El número pasado a la llamada _exit()
/ exit_group()
system (a veces denominado código de salida para evitar la ambigüedad con el estado de salida, que también se refiere a una codificación del código de salida o el número de señal e información adicional dependiendo de si el proceso se cerró o salió normalmente) ) es de 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 31 ) a 2147483647 (2 31 -1).
Sin embargo, en todos los sistemas, cuando el proceso padre (o la subreaper niño o init
si el padre murió) utiliza el wait()
, waitpid()
, wait3()
, wait4()
las llamadas al sistema para recuperar, sólo los 8 bits inferiores de la misma son disponibles (valores de 0 a 255 (2 8 - 1)).
Cuando se usa la 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 la waitid()
API, aunque es probable que eso cambie en el futuro.
En general, solo querrá usar los valores 0 (generalmente significa éxito) a 125 solamente, 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á ejecutando y 126 y 127 para especiales condiciones
Es posible que desee usar 126 a 255 exit()
para significar lo mismo que para el shell $?
(como cuando lo hace un script ret=$?; ...; exit "$ret"
). Usar valores fuera de 0 -> 255 generalmente no es útil. Por lo general, solo haría eso si sabe que el padre usará la waitid()
API en sistemas que no se truncan y si necesita el rango de valores de 32 bits. Tenga en cuenta que si lo hace, exit(2048)
por ejemplo, los padres lo verán como un éxito utilizando las wait*()
API tradicionales .
Más información en:
Es de esperar que las preguntas y respuestas contesten la mayoría de sus otras preguntas y aclaren qué se entiende por estado de salida . Agregaré algunas cosas más:
Un proceso no puede finalizar a menos que se elimine o llame a las llamadas _exit()
/ exit_group()
system. Cuando regresa de main()
in C
, la libc llama a esa llamada del sistema con el valor de retorno.
La mayoría de los idiomas tienen una exit()
función que envuelve esa llamada del sistema y el valor que toman, si lo hay, generalmente se pasa como es a la llamada del sistema. (tenga en cuenta que, en general, hacen más cosas como la limpieza realizada por la exit()
función de C que vacía los buffers estándar, ejecuta los atexit()
ganchos ...)
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) = ?
Algunos proyectiles se quejan cuando usa 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 indefinido si el valor pasado a la exit
construcción especial está fuera de 0-> 255.
Algunos proyectiles muestran algunos comportamientos inesperados si lo haces:
bash
(y mksh
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)'
Es decir, ejecutar otro comando en el mismo proceso que puede llamar a la llamada del sistema con el valor que desee.
como se mencionó en ese otro Q&A, 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 exit_group()
, se mata 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
.
¹ Sin embargo, es probable que eso cambie en la próxima versión. Ahora que el desarrollo ksh93
se ha asumido como un esfuerzo comunitario fuera de AT&T, ese comportamiento, aunque alentado de alguna manera por POSIX, está siendo revertido
return
Por supuesto, es un estado integrado de shell.