Intenté un siguiente script:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
El resultado para el script anterior fue:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
Sin embargo, esperaba que también se llamara a trap en la salida foo1
, que se llama en una subshell.
- ¿Se espera esto?
- ¿Es
trap
heredado por una subshell? - En caso afirmativo, ¿en qué caso lo
trap
hereda una subshell?
Respuestas:
Los manipuladores de trampas nunca son heredados por subcapas. Esto lo especifica POSIX :
Tenga en cuenta que las señales ignoradas (
trap '' SIGFOO
) permanecen ignoradas en el subshell (y también en los programas externos lanzados por el shell).fuente
set -E
para que las subcapas hereden las trampas, pero es REALMENTE difícil hacerlo bien (al menos en mi experiencia).trap
no se propaga a subcapas, pero algunas formas permiten que la subcadena informe las trampas de la capa principal y otras no. Hice algunas pruebas en macos con bash.GNU bash, versión 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, versión 3.2.57 (1) -release (x86_64-apple-darwin16):
Es bueno saber que
trap_output="$(trap)"
funcionará para capturar la captura de salida. No puedo pensar en otra forma de hacerlo si eso no funcionó, ademástrap >trap_output_file
de enviarlo a un archivo (no funcionará en Fifobash 3.2.57
) y luego volver a leerlo contrap_output="$(<trap_output_file)"
Fifo no funcionará
bash 3.2.57
porquetrap &
está vacíobash 3.2.57
pero nobash 4.4.12
GNU bash, versión 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, versión 3.2.57 (1) -release (x86_64-apple-darwin16):
fuente
trap
las definiciones no se propagan a subcapas.Verificar por:
trap "echo bla" 1 2 3"
(trap)
fuente
(trap)
como un caso especial, de modo que el subshell puede informar (pero no usar) las trampas del shell principal. Entonces esa prueba no siempre es confiable.ksh88
,bosh
(schily Bourne Shell) yheirloom-sh
. Tienes razón: seksh93
comporta de manera diferente.bash
no genera nada si llamas(trap)
.