Eu tentei um script a seguir:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
A saída para o script acima foi:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
No entanto, eu esperava que a armadilha fosse chamada na saída foo1
também, que é chamada em um subshell.
- Isso é esperado?
- É
trap
herdado por um subshell? - Se sim, em que caso é
trap
herdado por um subshell?
Respostas:
Os manipuladores de interceptação nunca são herdados por subshells. Isso é especificado pelo POSIX :
Observe que os sinais ignorados (
trap '' SIGFOO
) permanecem ignorados no subshell (e também nos programas externos lançados pelo shell).fonte
set -E
, para que sub-conchas herdem armadilhas, mas é MUITO complicado acertar (pelo menos na minha experiência).trap
não é propagado para subshells, mas algumas maneiras permitem que o subshell relate as armadilhas do shell pai e outras não. Fiz alguns testes em macos com bash.Lançamento do GNU bash, versão 4.4.12 (1) (x86_64-apple-darwin16.3.0):
GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin16):
É bom saber que
trap_output="$(trap)"
isso funcionará para capturar a saída de interceptação. Não consigo pensar em outra maneira de fazê-lo se isso não funcionasse além de fazertrap >trap_output_file
a saída para um arquivo (o fifo não funcionarábash 3.2.57
) e depois lê-lo novamente comtrap_output="$(<trap_output_file)"
O fifo não funciona
bash 3.2.57
porquetrap &
está vazio,bash 3.2.57
mas não estábash 4.4.12
Lançamento do GNU bash, versão 4.4.12 (1) (x86_64-apple-darwin16.3.0):
GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin16):
fonte
trap
as definições não são propagadas para subcascas.Verifique por:
trap "echo bla" 1 2 3"
(trap)
fonte
(trap)
como um caso especial, para que o subshell possa relatar (mas não realmente usar) as armadilhas do shell pai. Portanto, esse teste nem sempre é confiável.ksh88
,bosh
(Schily Bourne Shell) eheirloom-sh
. Você está correto:ksh93
se comporta de maneira diferente.bash
não produz nada se você ligar(trap)
.