-
Outras partes do código devem poder chamar a função de limpeza, independentemente de estar dentro ou fora das {} chaves, desde que seja declarada antes de sua chamada real (na verdade, não é sobre uma antiga linha de script ) e no mesmo nível de shell bash (
$BASH_SUBSHELL
). -
(EDITED) A armadilha pode ser chamada se já foi declarada e tem que ser declarada no mesmo nível de subnível. Aparentemente, o sinal está em cascata, como mostra o código abaixo quando você o executa.
.
#!/usr/bin/env bash
trap "echo ok 0" 2
(
echo subshell: $BASH_SUBSHELL
trap "echo ok 1" 2
(
echo subshell: $BASH_SUBSHELL
trap "echo ok 2" 2;
sleep 100
#now test the trap
)
)
Resultado:
subshell: 0
subshell: 1
subshell: 2
^Cok 2
ok 1
ok 0
Mas não os tubos:
#!/bin/bash
trap "echo ok 0" 2
{
echo $BASH_SUBSHELL
trap "echo ok 1" 2
} | \
{
trap "echo ok 2" 2
read line; echo $line;
sleep 100
#now Ctrl-c
}
Resultado:
1
^Cok 2
ok 0
- As chaves constroem uma função anônima. A função mantém o nível do shell bash, mas não em todos os contextos.
Analise o script abaixo para ilustração. Execute-o em um terminal e veja o que ele produz.
#!/bin/bash
k=k
msg='echo line: $LINENO, \$k: $k, BASH_SUBSHELL: $BASH_SUBSHELL'
eval $msg
{
k=a
eval $msg
} &
sleep 1
#job %1 should be done by now
jobs
eval $msg
{
k=b
eval $msg
} | {
read line; echo $line;
eval $msg
}
eval $msg
{
k=c
eval $msg
}
eval $msg
{ trap 'echo -e "\nterminating"; exit;' 2;}
sleep 100 #try out the trap by hitting Ctrl-c
- A solução para o seu script é:
a. Mova a armadilha antes do primeiro {
.
b. Tente mover a função de limpeza antes do primeiro {
usando algumas construções inteligentes como eval
(veja no meu script como funciona). Se não for possível, tente construir uma função de proxy nas chaves para uma mais genérica antes delas e corrija o que está faltando em sua chamada na armadilha.