
これを持っているとしましょう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
ため、おそらく解決策を見逃したのでしょう。
Chromiumのような「本物の」プログラムが送信時に行うことはこれだと思いますSIGTERM
からhttps://major.io/2010/03/18/sigterm-vs-sigkill/
アプリケーションは、SIGTERM を受信したら何を実行するかを決定できます。ほとんどのアプリケーションはリソースをクリーンアップして停止しますが、そうしないアプリケーションもあります。
答え1
trap
呼び出しプロセスシグナル自体に反応します。ただし、シグナルを受信する前に呼び出す必要があります。つまり、スクリプトの先頭で呼び出す必要があります。
kill -- -$$
さらに、スクリプトにも信号を送る を使用する場合は、killを実行する前にトラップをクリアする必要があります。そうしないと、無限に終了してしまいます。殺す && 罠にかけるループ。
例えば:
#!/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