SIGINT または SIGTERM が子プロセスではなく親スクリプト自体に送信されたときにコマンドまたは関数を実行します。

SIGINT または SIGTERM が子プロセスではなく親スクリプト自体に送信されたときにコマンドまたは関数を実行します。

これを持っているとしましょう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_scriptSIGINTSIGTERM

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

関連情報