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 anteriores:
Los controladores INT y TERM no se dan por vencidos cuando pruebo: manejan el error y el shell vuelve a salir (y esto no es demasiado sorprendente). Por lo tanto, me aseguro de que la limpieza salga después, y en el caso de las señales siempre usa 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, destapo el controlador de salida y lo llamo yo mismo (que funcionará en cualquier shell independientemente del comportamiento).
Atrapo la salida porque los scripts de shell pueden salir antes de llegar al fondo: errores de sintaxis, set -e y un retorno distinto de cero, simplemente llamando a exit. No puede confiar en que un shellscript llegue al fondo.
SIGQUIT es Ctrl- \ si nunca lo has probado. Obtiene un coredump adicional. Así que creo que también vale la pena atraparlo, incluso si es un poco oscuro.
La experiencia pasada dice que si (como yo) siempre presiona Ctrl-C varias veces, a veces lo atrapará 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.
INT TERM EXITel código de limpieza se ejecuta dos veces cuandoSIGTERMoSIGINTse recibe.