Aquí hay un script simple que configura un directorio temporal en el directorio actual y una trampa para eliminarlo al salir.
#filename: script
set -x
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"
Si hago ksh script sleep 100
o bash script sleep 100
lo interrumpo con, C-C
la trampa se ejecuta y el directorio se elimina. No funciona con dash
. ¿Por qué? ¿Es esto un error o un comportamiento previsto?
Respuesta1
zsh
, pdksh
(aunque no las versiones recientes mksh
derivadas de eso) yash
, el shell Bourne se comporta como dash
.
Sólo bash
, ksh88
, ksh93
y mksh
comportarse de otra manera.
La especificación POSIX no es clara sobre cuál debería ser el comportamiento correcto, pero no hay nada allí que diga que el shell puede anular el controlador predeterminado para la SIGINT
(u otra) señal.
Dice que EXIT
la acción de captura debe evaluarse cuando exit
se invoca, pero AFAICT, ni siquiera dice, por ejemplo, si debe evaluarse cuando el shell sale como resultado de condiciones de set -e
error set -u
como errores de sintaxis o fallas en funciones integradas especiales.
Para poder ejecutar EXIT
la trampa al recibir una señal, el shell necesitaría instalar un controlador en esa señal.
Eso es lo ksh
que mksh
hacen bash
, pero la lista de señales que manejan es diferente entre las tres implementaciones. Las únicas señales comunes entre los 3 parecen ser INT
, QUIT
, y TERM
.ALRM
HUP
Si desea que la EXIT
trampa funcione con algunas señales, la forma portátil sería manejar esas señales usted mismo:
trap 'exit 1' INT HUP QUIT TERM ALRM USR1
trap 'cleanup' EXIT
Sin embargo, ese enfoque no funciona con zsh
, que no ejecuta EXIT
trap si exit
se llama desde un controlador de trampas.
Tampoco informa tu muerte por señal a tus padres.
Entonces, en su lugar, podrías hacer:
for sig in INT QUIT HUP TERM ALRM USR1; do
trap "
cleanup
trap - $sig EXIT
kill -s $sig "'"$$"' "$sig"
done
trap cleanup EXIT
Ahora, tenga en cuenta que si llegan más señales mientras ejecuta cleanup
, cleanup
es posible que se ejecute nuevamente. Es posible que desee asegurarse de que cleanup
funcione correctamente si se invoca varias veces y/o ignorar las señales durante su ejecución.
Respuesta2
Advertencia: exit
no se garantiza que funcione, en su lugar debe utilizarEXIT
Dado que el estándar POSIX no define si la EXIT
trampa también debe ejecutarse en caso de una señal y dado que Bourne Shell no llama a la EXIT
trampa en el caso que mencionas, es obvio que estás entrandono especificadocomportamiento.