Ao capturar um sinal em um shell script, os comandos trap não são executados até que o comando atual seja concluído. Por exemplo, considere o seguinte script de shell:
#!/bin/bash
trap 'echo "SIGTERM caught"' SIGTERM
i=0
while : ; do
echo "$((++i))"
timeout 10 yes >/dev/null
done
Se alguém executar este script e tentar enviar SIGTERM para o processo, a instrução echo na função trap não será executada até a conclusão do comando ativo.
Ao fazer o background de um comando e usar wait, os sinais podem ser manipulados durante a execução do comando, por exemplo,
#!/bin/bash
trap 'echo "SIGTERM caught"; [[ "$pid" ]] && echo "Killing $pid" && kill "$pid"' SIGTERM
i=0
while : ; do
echo "$((++i))"
timeout 10 yes >/dev/null &
pid=$!
wait
done
No entanto, enquanto o SIGTERM agora é detectado imediatamente, isso faz com que o processo responda incorretamente a outros sinais, como o SIGINT. Por exemplo, se o script acima for executado, ele não poderá ser finalizado pelo SIGINT se o SIGTERM tiver sido enviado mais de alguns instantes antes. Por exemplo, se $pid
for o ID do processo do script shell, qualquer um dos itens a seguir eliminará o processo (no último caso, o processo é interrompido pelo SIGINT antes que ele tenha uma chance de responder ao SIGTERM):
kill -SIGINT "$pid"
kill "$pid"; kill -SIGINT "$pid"
considerando que o seguinte não será (o processo trava e deve ser eliminado ao entregar SIGKILL):
kill "$pid"; sleep 0.01; kill -SIGINT "$pid"
SIGTERM caught
# process hangs at this point
Quais mudanças precisam ser feitas na armadilha para evitar manuseio inadequado de outros sinais?