
Eu tento muito entender o que estou fazendo de errado e por quê?
Eu tenho um launch.sh
script que inicia o process.sh
.
lançamento.sh
#!/bin/bash
while true; do
./process.sh
done
processo.sh
#!/bin/bash
function signalHandler() {
for i in {1..2}; do
sleep 0.1s
echo "process.sh: cleanup $i"
done
exit 130
}
trap "signalHandler" "SIGINT"
while true; do
sleep 1s
done
quando eu corro
./launch.sh &
e então mate-o com
kill -s SIGINT -$!
onde $!
pega o PID do último comando (launch.sh) e o sinal de menos envia o sinal para todos os filhos, depois launch.sh
continua. Por que?
Eu esperava o seguinte comportamento (de acordo com este blogSinal e Bash) :
o shell A com o script launch.sh
em execução em segundo plano é interrompido, o Bash espera até process.sh
terminar. Como process.sh
retorna anormalmente (saída 130) devido ao manipulador de sinal em process.sh
, o shell A deve sair. Por que não?
Se o status desse filho indicar que ele saiu de forma anormal devido a esse sinal, o shell limpa, remove seu manipulador de sinal e se mata novamente para acionar a ação padrão do sistema operacional (saída anormal). Alternativamente, ele executa o manipulador de sinal do script conforme definido com trap e continua.
Responder1
Primeiro, exit 130
não é uma saída anormal. É uma saída normal, com status de saída 130. Como pode ser visto emman 3 wait
(POSIX):
If the information pointed to by stat_loc was stored by a call to
waitpid() that specified the WUNTRACED and WCONTINUED flags,
exactly one of the macros WIFEXITED(*stat_loc), WIFSIGNALED(*stat_loc),
WIFSTOPPED(*stat_loc), and WIFCONTINUED(*stat_loc) shall evaluate to
a non-zero value.
WIFEXITED
verifica a saída normal e WIFSIGNALLED
é encerrado devido a um sinal não capturado. Como estes são mutuamente exclusivos, an exit 130
é normal.
O fato de o status de saída ser 130 quando um processo morre pelo SIGINT é porque o bash o define como 130 fora do processo porque detectou uma saída devido ao SIGINT:Por que o bash define $? (status de saída) para diferente de zero em Ctrl-C ou Ctrl-Z?
Segundo, um processo que lida com SIGINT e depois morre deve se matar com SIGINT. O wiki de Greg (um excelente recurso para coisas de shell) temuma nota sobre isso:
Se você optar por configurar um manipulador para SIGINT (em vez de usar a armadilha EXIT), você deve estar ciente de que um processo que sai em resposta a SIGINT devematar-se com SIGINTem vez de simplesmente sair, para evitar causar problemas ao chamador. Por isso:
trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT
Agora, se você mudou exit 130
para:
trap - INT
kill -INT $$
Você veria o comportamento esperado.