Execute o comando ou função quando SIGINT ou SIGTERM é enviado para o próprio script pai, não para os processos filhos

5

Digamos que eu tenha esse script.sh

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

echo "Some other text"
#other commands here
sleep infinity

Eu quero que script.sh execute a função exit_script sempre que receber SIGINT ou SIGTERM Por exemplo:

killall script.sh # it will send SIGTERM to my script

e quero que meu script execute isso

exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

Eu tentei implementar esse recurso usando trap

trap exit_script SIGINT SIGTERM

A pessoa que respondeu à minha pergunta provou que eu estava errado.
mas não funcionou porque trap parece reagir apenas aos sinais enviados aos processos filho / sub. Como iniciante, não consegui decifrar a página de manual do trap , por isso provavelmente perdi a solução.

Acho que é isso que programas "reais", como o Chromium, fazem quando você os envia SIGTERM

De link

The application can determine what it wants to do once a SIGTERM is received. While most applications will clean up their resources and stop, some may not.

    
por bosa djo 01.10.2016 / 16:03

1 resposta

9

trap reage ao próprio processo de chamada. Mas você deve chamá-lo antes que o sinal seja recebido. Quero dizer, no começo do seu roteiro.

Além disso, se você quiser usar kill -- -$$ , que envia o sinal também para o seu script, você precisa limpar a armadilha antes de executar o kill ou você terminará com um kill & & armadilha loop.

Por exemplo:

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    trap - SIGINT SIGTERM # clear the trap
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

trap exit_script SIGINT SIGTERM

echo "Some other text"
#other commands here
sleep infinity

Como explicado nos comentários, o problema é que o script recebe o sinal, mas está aguardando que o programa do sono termine antes de processar o sinal recebido. Portanto, você deve eliminar os processos filho (o processo de suspensão, neste caso) para executar a ação de interceptação. Você pode fazer isso com algo como o seguinte:

kill -- -$(pgrep script.sh)

Ou como indicado nos comentários:

killall -g script.sh
    
por 01.10.2016 / 16:17