captura de sinais sem interferir com outros sinais

2

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?

    
por user001 07.11.2017 / 00:24

0 respostas

Tags