1

トラップを使用して子プロセスにシグナルを転送することについて混乱しています。2 つのスクリプトがあるとします。

#!/bin/bash

# print the process id
echo $$

cleanup() {
    rv=$?
    echo "cleaning up $rv"
    exit
}

sleep 5
trap '' SIGTERM # trap cleanup SIGTERM
echo 'cant stop wont stop'
./b.sh
echo 'can stop will stop'
trap - SIGTERM
sleep 4
echo 'done'

b.sh

#!/bin/bash
sleep 4;
echo 'b done'

を実行a.shして別のウィンドウからプロセス グループを強制終了するとkill -- -PGID、SIGTERM は無視され、に渡されませんb.sh。しかしtrap cleanup SIGTERM、そうすると、SIGTERM は通過して終了しますb.sh。トラップが信号を渡す場合と渡さない場合があるのはなぜですか?

4

2 に答える 2

1

trapマニュアルページから:

トラップ [アクション条件 ...]

action が null ( "" ) の場合、指定された各条件が発生した場合、シェルはそれを無視します。

したがって、 を実行するTRAP '' SIGTERMと、SIGTERM条件は無視されます。代わりにスペース値を使用してみて、それが機能するかどうかを確認してください。

sleep 5
trap ' ' SIGTERM # Note the space (' ')!!

echo 'cant stop wont stop'
./b.sh

echo 'can stop will stop'
trap - SIGTERM

sleep 4
echo 'done'
于 2016-08-12T02:44:39.523 に答える
1

これは面白い。引用man 7 signal

fork(2) によって作成された子は、その親のシグナル処理のコピーを継承します。execve(2) の間、処理されたシグナルの処理はデフォルトにリセットされます。無視されたシグナルの処理は変更されません。

あなたの場合、子TERMは同じプロセスグループに属しているため、常に受け取ります。問題は、それで何をするかです。

親が を無視する TERMと、上記のルールにより、子も無視されるため、子は生き残ります。親が をキャッチ TERMすると、子のハンドラーがリセットされ、デフォルト アクションとして終了します。

于 2016-08-12T04:10:57.480 に答える