Saltar al contenido

“trampa … INT TERM EXIT” ¿es realmente necesario?

Solución:

Sí, hay una diferencia.

Este script saldrá cuando presione Ingresaro envíalo SIGINT o SIGTERM:

trap '' EXIT
echo ' --- press ENTER to close --- '
read response

Este script saldrá cuando presione Ingresar:

trap '' EXIT INT TERM
echo ' --- press ENTER to close --- '
read response

* Probado en sh, Intento, y Zsh. (ya no funciona en sh cuando agrega un comando para que se ejecute la trampa)


También está lo que dijo @Shawn: Ceniza y Pizca no atrape señales con EXIT.

Por lo tanto, para manejar las señales de manera robusta, es mejor evitar atrapar EXIT en conjunto, y use algo como esto:

cleanup() {
    echo "Cleaning stuff up..."
    exit
}

trap cleanup INT TERM
echo ' --- press ENTER to close --- '
read var
cleanup

La especificación POSIX no dice mucho sobre las condiciones que resultan en la ejecución de la trampa EXIT, solo sobre cómo debe verse su entorno cuando se ejecuta.

En el caparazón de cenizas de Busybox, su prueba de salida de trampa no hace eco de ‘TRAP’ antes de salir debido a SIGINT o SIGTERM. Sospecho que existen otros proyectiles que pueden no funcionar de esa manera también.

# /tmp/test.sh & sleep 1; kill -INT %1
# 
[1]+  Interrupt                  /tmp/test.sh
# 
# 
# /tmp/test.sh & sleep 1; kill -TERM %1
# 
[1]+  Terminated                 /tmp/test.sh
# 

Refinando la última respuesta, porque tiene problemas:

# Our general exit handler
cleanup() {
    err=$?
    echo "Cleaning stuff up..."
    trap '' EXIT INT TERM
    exit $err 
}
sig_cleanup() {
    trap '' EXIT # some shells will call EXIT after the INT handler
    false # sets $?
    cleanup
}
trap cleanup EXIT
trap sig_cleanup INT QUIT TERM

Puntos arriba:

Los controladores INT y TERM no me abandonan cuando hago la prueba; manejan el error y luego el shell vuelve a salir (y esto no es demasiado sorprendente). Así que me aseguro de que la limpieza finalice después y, en el caso de las señales, siempre use un código de error (y en el otro caso de una salida normal, conserva el código de error).

Con bash, parece que salir en el controlador INT también llama al controlador EXIT, por lo tanto, desenvuelvo el controlador de salida y lo llamo yo mismo (que funcionará en cualquier shell independientemente del comportamiento).

Capturo exit porque los scripts de shell pueden salir antes de llegar al final: errores de sintaxis, set -e y un retorno distinto de cero, simplemente llamando a exit. No puede confiar en que un shellscript llegue al final.

SIGQUIT es Ctrl- si nunca lo ha probado. Te da un coredump adicional. Así que creo que también vale la pena atraparlo, aunque sea un poco oscuro.

La experiencia pasada dice que si usted (como yo) siempre presiona Ctrl-C varias veces, a veces lo detectará a la mitad de la parte de limpieza de su script de shell, por lo que esto funciona, pero no siempre tan perfectamente como le gustaría.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *