これを持っているとしましょう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
が欲しいです script.sh
関数を実行するにはexit_script
SIGINT
またはSIGTERM
を受け取ったときはいつでも
killall script.sh # it will send SIGTERM to my script
スクリプトでこれを実行したい
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
kill -- -$$ # Sends SIGTERM to child/sub processes
}
trap
を使用してこの機能を実装しようとしました
trap exit_script SIGINT SIGTERM
私の質問に答えた人が私を誤解した。しかし、trap
は子/サブプロセスに送信されたシグナルにのみ反応するように見えるため、機能しませんでした。初心者としてtrap
のmanページを解読できなかったので、おそらく解決策を見逃しました。
これは、Chromiumのような「実際の」プログラムが送信するときにSIGTERM
が行うことだと思います。
From https://major.io/2010/03/18/sigterm-vs-sigkill/ から
アプリケーションは、SIGTERMを受信すると何をしたいかを決定できます。ほとんどのアプリケーションはリソースをクリーンアップして停止しますが、そうでないアプリケーションもあります。
trap
は、呼び出しプロセスのシグナル自体に反応します。ただし、信号を受信する前に呼び出す必要があります。つまり、スクリプトの冒頭です。
さらに、スクリプトにも信号を送信するkill -- -$$
を使用する場合は、killを実行する前にトラップをクリアする必要があります。そうしないと、無限kill && trapループで終了します。
例えば:
#!/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
コメントで説明されているように、問題はスクリプトが信号を受信するが、受信した信号を処理する前にスリーププログラムが終了するのを待っていることです。したがって、トラップアクションを実行するには、子プロセス(この場合はスリーププロセス)を強制終了する必要があります。次のような方法でそれを行うことができます:
kill -- -$(pgrep script.sh)
またはコメントで述べたように:
killall -g script.sh