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


11

私がこれを持っているとしましょう 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、子/サブプロセスに送信されたシグナルにのみ反応するように見えるため、機能しませんでした。初心者としては、trapmanページを解読できなかったので、おそらく解決策を見逃しました。

あなたがそれらを送るとき、それはChromiumのような「本当の」プログラムがすることだと思います SIGTERM

https://major.io/2010/03/18/sigterm-vs-sigkill/から

アプリケーションは、SIGTERMを受信すると、何を実行するかを決定できます。ほとんどのアプリケーションはリソースをクリーンアップして停止しますが、そうでないアプリケーションもあります。


2
一般に、礼儀正しい談話のために不適切であると誓う

提案を編集承認済みok、ok完了、面白くない私はそれを手に入れました
bosa djo

楽しいことが許されているわけではなく、単に攻撃的だと見なされているだけです。
猫、

1
@猫私はあなたの議論について考えました、そしてあなたは正しいです、私のtomfooleryのために申し訳ありません
djo

回答:


15

trap呼び出しプロセスのシグナル自体に反応します。ただし、信号を受信する前に呼び出す必要があります。つまり、スクリプトの冒頭です。

さらに、kill -- -$$スクリプトにも信号を送信するを使用する場合は、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

1
それが機能しないため、おそらく何かが足りないのですが、これが私がすることです。script.sh&; killall script.shは何もしません。
bosa djo 2016年

script.sh&;を実行します #それから私は私の仕事をします。killall script.shは、script.shを強制終了しません
djo

1
問題はおそらく、スクリプトがシグナルを受信したが、それを処理する前にスリーププログラムが終了するのを待っていることです。./script.sh & sleep 1 && kill -- -$(pgrep script.sh)スクリプトの子プロセスにもkillシグナルを送信してみてください。
zuazo 2016年

@zuazoこの興味深い重要な情報を回答に追加してください:)
cat

1
ニース、ボーザ・ディー。私はあなたの代替ソリューションを答えに追加しました;-)
zuazo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.