Nehmen wir an, ich habe dasscript.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
Ich möchte script.sh
die Funktion immer dann ausführen, exit_script
wenn sie empfängt SIGINT
oder SIGTERM
Zum Beispiel:
killall script.sh # it will send SIGTERM to my script
und ich möchte, dass mein Skript dies ausführt
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
kill -- -$$ # Sends SIGTERM to child/sub processes
}
Ich habe versucht, diese Funktion zu implementieren mittrap
trap exit_script SIGINT SIGTERM
Die Person, die meine Frage beantwortet hat, hat mir das Gegenteil bewiesen.
Aber es hat nicht funktioniert, weil es trap
anscheinend nur auf Signale reagiert, die an untergeordnete/untergeordnete Prozesse gesendet werden. Als Anfänger konnte ich trap
die Manpage nicht entziffern, also habe ich die Lösung wahrscheinlich übersehen.
Ich denke, das ist, was "echte" Programme wie Chromium tun, wenn Sie sie sendenSIGTERM
Aushttps://major.io/2010/03/18/sigterm-vs-sigkill/
Die Anwendung kann bestimmen, was sie tun möchte, sobald ein SIGTERM empfangen wird. Während die meisten Anwendungen ihre Ressourcen bereinigen und anhalten, tun dies manche nicht.
Antwort1
trap
reagiert selbst auf die Signale des aufrufenden Prozesses. Sie müssen es jedoch aufrufen, bevor das Signal empfangen wird. Ich meine, am Anfang Ihres Skripts.
Wenn Sie außerdem verwenden möchten kill -- -$$
, das das Signal auch an Ihr Skript sendet, müssen Sie die Falle löschen, bevor Sie den Kill ausführen, sonst erhalten Sie eine unendlichetöten und fangenSchleife.
Zum Beispiel:
#!/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
Wie in den Kommentaren erklärt, besteht das Problem darin, dass das Skript das Signal empfängt, aber wartet, bis das Sleep-Programm beendet ist, bevor es das empfangene Signal verarbeitet. Sie sollten also die untergeordneten Prozesse (in diesem Fall den Sleep-Prozess) beenden, um die Trap-Aktion auszuführen. Sie können das etwa mit Folgendem tun:
kill -- -$(pgrep script.sh)
Oder wie in den Kommentaren angegeben:
killall -g script.sh