¿Cuáles son los valores mínimos y máximos de los siguientes códigos de salida en Linux:
- El código de salida devuelto por un ejecutable binario (por ejemplo: un programa en C).
- El código de salida devuelto por un script bash (cuando se llama
exit
). - El código de salida devuelto por una función (al llamar
return
). Creo que esto es entre0
y255
.
linux
executable
function
exit-status
usuario271801
fuente
fuente
return
Por supuesto, es un estado integrado de shell.bash
shell. Algunos shells comozsh
pueden devolver cualquier valor firmado de 32 bits como forexit
. A algunos les gustarc
oes
pueden devolver datos de cualquiera de los tipos que admiten (escalar o lista). Consulte las preguntas y respuestas vinculadas para más detalles.Respuestas:
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 tipoint
, 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 elwait()
,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 elsi_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 lawaitid()
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 condicionesEs posible que desee usar 126 a 255
exit()
para significar lo mismo que para el shell$?
(como cuando lo hace un scriptret=$?; ...; 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á lawaitid()
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 laswait*()
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 demain()
inC
, 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 laexit()
función de C que vacía los buffers estándar, ejecuta losatexit()
ganchos ...)Ese es el caso de al menos:
De vez en cuando ves algunos que se quejan cuando usas un valor fuera de 0-255:
Algunos proyectiles se quejan cuando usa un valor negativo:
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
(ymksh
nopdksh
en el que se basa) se encarga de truncar el valor a 8 bits:Entonces, en esos shells, si desea salir con un valor fuera de 0-255, debe hacer algo como:
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 llamarexit_group()
, se mata con la señal correspondiente¹.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 revertidofuente
si_status
Linux?int
tener al menos 16 bits, POSIX requiere más o menos 32 bits y entornos de programación para tener un uint32_t . No sé si Linux es compatible con algún entorno de programación donde los ints no sean de 32 bits, nunca me he encontrado con ninguno.El mínimo es
0
, y eso se considera el valor de éxito. Todos los demás son un fracaso. El máximo255
también se conoce como-1
.Estas reglas se aplican tanto a los scripts como a otros ejecutables, así como a las funciones de shell.
Los valores más grandes dan como resultado el módulo 256.
fuente
bash
otros u otros más utilizados) el código de salida pasado alexit
incorporado no se trata como módulo-256, y en su lugar causa un error. (Por ejemplo, lo comúnexit -1
no es un equivalente portátilexit 255
en la mayoría de los shells). Y siexit(-1)
el nivel C es equivalente aexit(255)
un detalle que de hecho es seguro que funciona, pero se basa en el comportamiento definido de implementación (aunque esto no es un problema en los sistemas modernos que es probable que use en la práctica).exit(1)
parámetro a 8 bits.Esto parece muy simple, pero ¡ay!
El lenguaje C (y siguiendo que la mayoría de los otros lenguajes directa o indirectamente) requiere que regresar
main
sea equivalente a llamarexit
con el mismo argumento que el valor de retorno. Este es un número entero (el tipo de retorno es muy claramenteint
), por lo que, en principio, la gama seríaINT_MIN
aINT_MAX
.Sin embargo, POSIX establece que solo los 8 bits más bajos pasados
exit
estarán disponibles para un proceso padre en espera, literalmente como si fuera "estado y 0xFF" .Entonces, en la práctica, el código de salida es un entero (todavía firmado) del cual solo se establecen los 8 bits más bajos.
El mínimo será -128, y el máximo 127. Espera, eso no es cierto. Será de 0 a 255.Pero, por supuesto, no puede ser tan simple . En la práctica, Linux (o más bien bash) lo hace de manera diferente . El rango válido de códigos de retorno es de 0 a 255 (es decir, sin signo).
Para estar en el lado seguro en términos de evitar confusiones, probablemente sea una buena idea asumir que los códigos de retorno no están firmados y emitir todo lo que devuelve
wait
sin firmar. De esa manera es consistente con lo que ves en un shell. Dado que los bits superiores (incluido el más significativo) se borran, eso ni siquiera es "incorrecto" porque, aunque técnicamente está firmado, los valores reales siempre están sin signo (ya que el bit de signo nunca se establece).También ayuda a evitar el error común de comparar un código de salida
-1
, que por alguna extraña razón nunca parece aparecer incluso cuando sale un programa-1
(¡bueno, adivina por qué!).Acerca de su último punto, volviendo de una función, si esta función es
main
, entonces vea arriba. De lo contrario, depende del tipo de retorno de la función, en principio podría ser cualquier cosa (incluidovoid
).fuente
waitid()
se presentó.waitid()
hace exactamente lo mismo, ligeramente diferente. Espera una identificación particular o cualquier hilo, y escribe los resultados en lasiginfo_t
estructura apuntada a dondesi_status
estáint
(así que ... firmado , igual). Aún así,exit()
solo pasa los 8 bits más bajos, así que ... absolutamente lo mismo debajo del capó.exit()
pasa los 32 bits del parámetro al kernel ywaitid()
devuelve los 32 bits del código de salida. Tal vez revisó Linux donde a nadie le importa arreglar errores. Si no me cree,exit
, en particular la segunda línea bajo "Descripción" que dice: "aunque solo los 8 bits menos significativos (es decir, estado y 0377) estarán disponibles para un proceso padre en espera " . Así es como funciona una implementación conforme: 8 bits más bajos, no 32. ¿Tiene una referencia para 32 bits que se transmiten?waitid()
y lasiginfo_t
estructura pasada alSIGCHLD
controlador devuelve todos los 32 bits delexit()
parámetro.Los códigos de salida de cualquier proceso, ya sea un ejecutable binario, un script de shell o cualquier otra cosa, varían de 0 a 255. Es posible pasar un valor mayor a
exit()
, pero solo los 8 bits inferiores del estado están disponibles para otros procesos a travéswait()
.Se puede declarar que la función de CA devuelve casi cualquier tipo. Los límites de su valor de retorno están determinados completamente por ese tipo: por ejemplo, -128 a 127 para una función que regresa
signed char
, o 0 a 4.2 mil millones para una función que regresaunsigned int
, o cualquier número de punto flotante hasta e incluyendoinf
para una función que regresadouble
. Y eso sin contar los tipos no numéricos, comovoid *
o unstruct
...fuente