トラップコマンドが見つかりません。 [閉じる]

トラップコマンドが見つかりません。 [閉じる]

この奇妙な動作が発生しました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結果は受信した信号によって異なります。

  1. 受信信号のPIDは外部標準PIDです。

    それでもsleepコマンドが完了するのを待つ必要があります。

    done inner process
    SIGINT in outer
    
  2. 受信信号のPIDは内部スクリプトのPIDです。

    それでもsleepコマンドが完了するのを待つ必要があります。

    SIGINT: command not found
    done inner process
    
  3. 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

別の質問は、内部スクリプトトラップ機能が呼び出された理由を尋ねましたが、そうではありません。眠っているプロセスが終了し、スクリプトが次の行に移動します。

関連情報