Disons que j'ai ça 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
Je veux script.sh
exécuter la fonction exit_script
chaque fois qu'elle reçoit SIGINT
ou SIGTERM
Par exemple:
killall script.sh # it will send SIGTERM to my script
et je veux que mon script exécute cela
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
kill -- -$$ # Sends SIGTERM to child/sub processes
}
J'ai essayé d'implémenter cette fonctionnalité en utilisant trap
trap exit_script SIGINT SIGTERM
La personne qui a répondu à ma question m'a donné tort.
mais cela n'a pas fonctionné car il trap
semble ne réagir qu'aux signaux envoyés aux processus enfants / sous. En tant que débutant, je ne pouvais pas déchiffrer trap
la page de manuel de donc j'ai probablement raté la solution.
Je suppose que c'est ce que font les "vrais" programmes comme Chromium lorsque vous les envoyez SIGTERM
Depuis https://major.io/2010/03/18/sigterm-vs-sigkill/
L'application peut déterminer ce qu'elle veut faire une fois qu'un SIGTERM est reçu. Bien que la plupart des applications nettoient leurs ressources et s'arrêtent, certaines peuvent ne pas le faire.
Réponses:
trap
réagit aux signaux du processus appelant lui-même. Mais vous devez l'appeler avant la réception du signal. Je veux dire, au début de votre script.De plus, si vous souhaitez utiliser
kill -- -$$
, qui envoie également le signal à votre script, vous devez effacer le piège avant d'exécuter le kill ou vous terminerez avec une boucle kill && trap infinie .Par exemple:
Comme expliqué dans les commentaires, le problème est que le script reçoit le signal mais attend la fin du programme de veille avant de traiter le signal reçu. Donc, vous devez tuer les processus enfants (le processus de veille dans ce cas) afin d'exécuter l'action d'interruption. Vous pouvez le faire avec quelque chose comme ce qui suit:
Ou comme indiqué dans les commentaires:
la source
./script.sh & sleep 1 && kill -- -$(pgrep script.sh)
d'envoyer un signal d'arrêt aux processus enfants de votre script.