この奇妙な動作が発生しましたtrap
。
~によるとトラップマンページ:
無視されないトラップは、サブシェルに入るとデフォルトの動作に設定されます。これは、新しいトラップを設定するためにサブシェルでTrapコマンドを使用できないという意味ではありません。
私が説明する方法は次のとおりです。
- スクリプトがシグナルAをキャプチャすると、対応するサブシェルもシグナルAをキャプチャしますが、基本的なアクションを実行します。
- サブシェルは、同じ信号をキャプチャするために別のアクションを指定することもできます。
私の理解をテストするために2つのスクリプトがあります。
outerscript.sh
#!/bin/bash
trap "echo SIGINT in outer" SIGINT
echo PID of outer process: $$
echo -----------;
./innerscript.sh
innerscript.sh
#!/bin/bash
echo start inner script
echo PID of inner process: $$
trap "SIGINT in inner, do graceful shutdown" SIGINT
sleep 10s
echo done inner process
その後、外部スクリプトを実行すると、./outerscript.sh
外部スクリプトが内部スクリプトを呼び出し、図のようにサブシェルを生成します。
SIGINT
睡眠コマンド中に次のように送信します。kill -SIGINT <pid>
PID結果は受信した信号によって異なります。
受信信号のPIDは外部標準PIDです。
それでもsleepコマンドが完了するのを待つ必要があります。
done inner process SIGINT in outer
受信信号のPIDは内部スクリプトのPIDです。
それでもsleepコマンドが完了するのを待つ必要があります。
SIGINT: command not found done inner process
PID受信信号はスリープ信号である。
sleepコマンドが完了するのを待つ必要はありません。
done inner process
質問
2)の場合、このようなエラーが発生するのはなぜですか?私は内部スクリプトがトラップ機能をトリガーすると予想しました。
3)の場合、内部スクリプトのトラップ機能をトリガーするのはなぜですか?私はそれが自分で終了し、通常は内部スクリプトプロセスに戻ると予想しました。
答え1
質問が2つあります。ケース2のエラーは、システムにSIGINTというコマンドがないために発生します。 OPは
trap "SIGINT in inner, do graceful shutdown" SIGINT
しかし、おそらく必要なコマンドは
trap "echo SIGINT in inner, do graceful shutdown" SIGINT
別の質問は、内部スクリプトトラップ機能が呼び出された理由を尋ねましたが、そうではありません。眠っているプロセスが終了し、スクリプトが次の行に移動します。