Los procesos pueden llamar a la llamada del _exit()sistema (en Linux, ver también exit_group()) con un argumento entero para informar un código de salida a su padre. Aunque es un número entero, solo los 8 bits menos significativos están disponibles para el padre (la excepción es cuando se usa waitid()o maneja en SIGCHLD en el padre para recuperar ese código , aunque no en Linux).
El padre generalmente hará un wait()o waitpid()para obtener el estado de su hijo como un entero (aunque también waitid()se puede usar una semántica algo diferente).
En Linux y en la mayoría de los Unices, si el proceso finalizó normalmente, los bits 8 a 15 de ese número de estado contendrán el código de salida que se le pasó exit(). De lo contrario, los 7 bits menos significativos (0 a 6) contendrán el número de señal y el bit 7 se establecerá si se volcó un núcleo.
perl's, $?por ejemplo, contiene ese número establecido por waitpid():
$ perl -e 'system q(kill $$); printf "%04x\n", $?'
000f # killed by signal 15
$ perl -e 'system q(kill -ILL $$); printf "%04x\n", $?'
0084 # killed by signal 4 and core dumped
$ perl -e 'system q(exit $((0xabc))); printf "%04x\n", $?'
bc00 # terminated normally, 0xbc the lowest 8 bits of the status
Los shells tipo Bourne también hacen que el estado de salida del último comando de ejecución en su propia $?variable. Sin embargo, no contiene directamente el número devuelto por waitpid(), sino una transformación, y es diferente entre los shells.
Lo que es común entre todos los shells es que $?contiene los 8 bits más bajos del código de salida (el número pasado exit()) si el proceso terminó normalmente.
Donde difiere es cuando el proceso termina con una señal. En todos los casos, y eso es requerido por POSIX, el número será mayor que 128. POSIX no especifica cuál puede ser el valor. Sin embargo, en la práctica, en todos los shells tipo Bourne que conozco, los 7 bits más bajos $?contendrán el número de señal. Pero, ¿dónde nestá el número de señal?
en ash, zsh, pdksh, bash, el shell Bourne, $?es 128 + n. Lo que eso significa es que en esos proyectiles, si obtienes uno $?de 129, no sabes si es porque el proceso salió exit(129)o si la señal lo mató 1( HUPen la mayoría de los sistemas). Pero la razón es que los shells, cuando salen ellos mismos, por defecto devuelven el estado de salida del último comando salido. Al asegurarse de $?que nunca sea mayor que 255, eso permite tener un estado de salida consistente:
$ bash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
bash: line 1: 16720 Terminated sh -c "kill \$\$"
8f # 128 + 15
$ bash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
bash: line 1: 16726 Terminated sh -c "kill \$\$"
8f # here that 0x8f is from a exit(143) done by bash. Though it's
# not from a killed process, that does tell us that probably
# something was killed by a SIGTERM
ksh93, $?Es 256 + n. Eso significa que a partir de un valor de $?usted puede diferenciar entre un proceso muerto y no muerto. Las versiones más nuevas de ksh, al salir, si $?eran superiores a 255, se suicidan con la misma señal para poder informar el mismo estado de salida a su padre. Si bien eso suena como una buena idea, eso significa que kshgenerará un volcado de núcleo adicional (posiblemente sobrescribiendo el otro) si el proceso fue eliminado por una señal generadora de núcleo:
$ ksh -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
ksh: 16828: Terminated
10f # 256 + 15
$ ksh -c 'sh -c "kill -ILL \$\$"; exit'; printf '%x\n' "$?"
ksh: 16816: Illegal instruction(coredump)
Illegal instruction(coredump)
104 # 256 + 15, ksh did indeed kill itself so as to report the same
# exit status as sh. Older versions of `ksh93` would have returned
# 4 instead.
Donde incluso podría decir que hay un error es que se ksh93suicida incluso si $?proviene de una función return 257realizada por:
$ ksh -c 'f() { return "$1"; }; f 257; exit'
zsh: hangup ksh -c 'f() { return "$1"; }; f 257; exit'
# ksh kills itself with a SIGHUP so as to report a 257 exit status
# to its parent
yash. yashofrece un compromiso Vuelve 256 + 128 + n. Eso significa que también podemos diferenciar entre un proceso cancelado y uno que finalizó correctamente. Y al salir, informará 128 + nsin tener que suicidarse y los efectos secundarios que puede tener.
$ yash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
18f # 256 + 128 + 15
$ yash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
8f # that's from a exit(143), yash was not killed
Para obtener la señal del valor de $?, la forma portátil es usar kill -l:
$ /bin/kill 0
Terminated
$ kill -l "$?"
TERM
(para portabilidad, nunca debe usar números de señal, solo nombres de señal)
En los frentes no Bourne:
csh/ tcshe fishigual que el shell Bourne, excepto que el estado está en $statuslugar de $?(tenga en cuenta que zshtambién establece la $statuscompatibilidad con csh(además de $?)).
rc: El estado de salida está en $statustambién, pero cuando matado por una señal, dicha variable contiene el nombre de la señal (como sigtermo sigill+coresi se generó un núcleo) en lugar de un número, que es otra prueba del diseño bien de que shell .
es. El estado de salida no es una variable. Si te importa, ejecutas el comando como:
status = <={cmd}
que devolverá un número sigtermo me sigsegv+coregusta en rc.
Tal vez para completar, deberíamos mencionar zshlas matrices 's $pipestatusy bash' $PIPESTATUSque contienen el estado de salida de los componentes de la última tubería.
Y también para completar, cuando se trata de funciones de shell y archivos de origen, las funciones por defecto regresan con el estado de salida del último comando ejecutado, pero también pueden establecer un estado de retorno explícitamente con el returnincorporado. Y vemos algunas diferencias aquí:
bashy mksh(desde R41, una regresión ^ Wchange aparentemente introducida intencionalmente ) truncará el número (positivo o negativo) a 8 bits. Entonces, por ejemplo, return 1234se establecerá $?en 210, return -- -1se establecerá $?en 255.
zshy pdksh(y derivados distintos de mksh) permiten cualquier entero decimal con signo de 32 bits (-2 31 a 2 31 -1) (y truncan el número a 32 bits).
ashy yashpermitir cualquier número entero positivo de 0 a 2 31 -1 y devolver un error para cualquier número de eso.
ksh93para return 0al return 320conjunto $?como es, pero para cualquier otra cosa, truncado a 8 bits. Tenga en cuenta, como ya se mencionó, que devolver un número entre 256 y 320 podría causar la kshmuerte al salir.
rcy espermitir devolver cualquier cosa, incluso listas.
También tenga en cuenta que algunos shells también usan valores especiales de $?/ $statuspara informar algunas condiciones de error que no son el estado de salida de un proceso, como 127o 126para el comando no encontrado o no ejecutable (o error de sintaxis en un archivo de origen) ...
killall myScripttrabajos, por lo tanto, el retorno del killall (¡y no del script!) es 0. Podría colocar unkill -x $$[x como el número de señal, y $$ generalmente expandido por el shell al PID de ese script (funciona en sh, bash, ...)] dentro del script y luego pruebe cuál era su núcleo de salida.