salir de la trampa en dash vs ksh y bash

salir de la trampa en dash vs ksh y bash

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 100o bash script sleep 100lo interrumpo con, C-Cla 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 mkshderivadas de eso) yash, el shell Bourne se comporta como dash.

Sólo bash, ksh88, ksh93y mkshcomportarse 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 EXITla acción de captura debe evaluarse cuando exitse invoca, pero AFAICT, ni siquiera dice, por ejemplo, si debe evaluarse cuando el shell sale como resultado de condiciones de set -eerror set -ucomo errores de sintaxis o fallas en funciones integradas especiales.

Para poder ejecutar EXITla trampa al recibir una señal, el shell necesitaría instalar un controlador en esa señal.

Eso es lo kshque mkshhacen 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.ALRMHUP

Si desea que la EXITtrampa 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 EXITtrap si exitse 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, cleanupes posible que se ejecute nuevamente. Es posible que desee asegurarse de que cleanupfuncione correctamente si se invoca varias veces y/o ignorar las señales durante su ejecución.

Respuesta2

Advertencia: exitno se garantiza que funcione, en su lugar debe utilizarEXIT

Dado que el estándar POSIX no define si la EXITtrampa también debe ejecutarse en caso de una señal y dado que Bourne Shell no llama a la EXITtrampa en el caso que mencionas, es obvio que estás entrandono especificadocomportamiento.

información relacionada