21

メインスクリプトによって制御されるスクリプトのコレクションがあります。メイン スクリプトでシグナルctrl+をトラップし、それを他のスクリプトに伝達したいと考えています。c他のスクリプトもこのシグナルを (メイン スクリプトから) トラップし、いくつかのクリーンアップを行う必要があります ...

私はkill -s SIGINT子に送信しようとしましたが、信号をキャッチできないようです (trap 'Cleanup' SIGINT子スクリプトで定義されていても)。

これを実現する方法の手がかりはありますか?

4

4 に答える 4

20

sleep 5次の例は、独自の処理を実行する 2 つの子 ( も実行) を開始した後に、何かを実行する親スクリプト ( ) を示していsleep 5ます。親が(何らかの理由で)終了すると、子に終了するように通知します(しないSIGINTでください。終了はSIGTERM、デフォルトのkillシグナルでもある によって通知されます)。その後、子供たちは の受信時に自分のことを行いSIGTERMます。子が独自のスクリプトである場合は、トラップ オンTERMをトラップ オンに変更しEXITて、終了の原因が何であれ (トラップ可能である限り) 子がクリーンアップできるようにすることをお勧めします。

の使用に注意してくださいwait。Bash は、シグナルを受信して​​も非組み込みコマンドの実行を中断しません。代わりに、コマンドが完了するのを待って、コマンドが完了した後にシグナルを処理します。を使用するwaitと、bash はすぐに待機を停止し、すぐにシグナルを処理します。

#!/usr/bin/env bash

trap 'echo parent shutting down; kill $(jobs -p)' EXIT

{ trap 'echo child 1 signaled' TERM; sleep 5 & wait; } &
{ trap 'echo child 2 signaled' TERM; sleep 5 & wait; } &

sleep 5
于 2010-08-05T11:53:18.840 に答える
4

試してみましたか:1)必要なすべてのスクリプト(マスター/チャイルド)でトラップをセットアップします2)プロセスグループ全体を強制終了するために、PIDがネゲートされたキルをマスターに送信します、つまり:

kill -15 -$PID

男を殺す | grep -C1 ネガティブ

于 2011-03-20T14:20:05.287 に答える
0

メイン ループの前のメインの親スクリプト ヘッダー:::

#Catch control-c and clean up testd instances if necessary
cleanup () {
    clear
    echo "Caught Signal.  Shutting Down MAIN."
    if [ "$MAIN_on" -eq 1 ]
    then
    M_shutdown
    fi
    exit 1
  }

スクリプトの本体では、サブプロセスを生成するときに、それぞれのプロセス ID を持つ配列を維持します。PID を配列にロードするには、値を最後に生成されたプロセスに設定します。たとえば、各サブシェルの生成後に次のように記述します。

proc_id_array[1]=$!

M_shutdow の内容は次のようになります...

M_shutdown () {

    if [ "$MAIN_on" -eq 1 ]
    then
    echo "Stopping Main"
    echo "shutting down active subscripts"
    count_proc_id=1


while [ "$count_proc_id" -lt "$max_proc_id" ]
        do

            kill ${proc_id_array[$count_proc_id]} > /dev/null 2>&1
            DATE=$(date +%m%d%y-%k:%M)
            echo "$DATE: ${proc_name_array[$count_proc_id]} \(PID: ${proc_id_array[$count_proc_id]}\) stopped." >> $logfile             
            proc_id_array[$count_proc_id]="A"
            count_proc_id=`expr $count_proc_id + 1`
        done


        echo "MAIN stopped"
        MAIN_on=0

        sleep 5
        else
        echo "MAIN already stopped."
        sleep 1
        fi
    }
于 2010-08-09T14:41:09.853 に答える
-1

「他のスクリプトはメイン スクリプトからこのシグナルをトラップする必要があります」とはどういう意味ですか? サブプロセス スクリプトでメイン スクリプトのコードを使用してシグナルをトラップするにはどうすればよいですか?

「メインスクリプトによって制御されるスクリプト」が何を意味するのか正確にはわからないため、多くのコードを書きたくありませんが、おそらくいくつかのサブプロセスを起動してから、他のサブプロセスかどうかをチェックする制御ループがありますスクリプトが終了し、終了ステータスを取得できますか? その場合、私にとって最も理にかなっていることは、各スクリプトが独自のトラップとクリーンアップを行うことです。メイン スクリプトがシグナルをトラップするとき、必要に応じてシグナルをすべての子に ( 経由でkill -s <signal> pid) 渡すことができます。子プロセスがシグナルをトラップすると、そのシグナルによって終了したことを示す終了ステータスを返すことができます。その後、メインはその終了ステータスを適切に処理できます。おそらく、その特定のシグナル自体を受信した場合と同じ方法です。(シェル関数はあなたの友達です。)

于 2010-03-26T19:02:29.587 に答える