1

次の 2 つの bash スクリプトがあるとします。

/tmp/トラッパー:

#!/bin/bash
trap 'echo trapper: ignoring USR1' USR1
"$(dirname $0)"/usr1er & p=$!
sleep 1
echo trapper: now killing usr1er
kill $p
echo trapper: sleeping
sleep 1
echo trapper: reached end of trapper

/tmp/usr1er:

#!/bin/bash
trap 'echo "usr1er: EXIT received, sending USR1"; kill -USR1 0' EXIT
while sleep 1;do echo usr1er: sleeping;done

trapper は USR1 をトラップし、単純に無視することになっています。usr1er を起動し、USR1 シグナルでそのプロセス グループを強制終了します。ここで、インタラクティブ シェルからスクリプトとして trapper を起動すると、usr1er が強制終了され、正常に終了します。

$ /tmp/trapper; echo done
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
/tmp/trapper: line 9: 16596 Terminated              "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper
done

試してみると$(/tmp/trapper)、シェル全体が終了します。同様に、次のように を呼び出す別のスクリプトを作成すると、次/tmp/trapperのようになり/tmp/outerます。

#!/bin/bash
"$(dirname $0)"/trapper
echo outer: reached end of outer

「到達した外側の終わり」を出力せずに強制終了されます。

$ /tmp/outer
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
/tmp/trapper: line 9: 23544 Terminated              "$(dirname $0)"/usr1er
User defined signal 1
trapper: ignoring USR1
trapper: reached end of trapper

なんで?

4

2 に答える 2

0

別のプロセスグループ/PGIDでプロセスを開始しない$()ようです(明らかに作業を行うため)。C-c

また、非対話型シェルも、子に対して個別の PGID を開始しません (set -m でジョブ制御をオンにしない限り)。

$ bash -c '/tmp/trapper;echo done'
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
$ /tmp/trapper: line 9: 17522 Terminated              "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper

「done」は出力されないことに注意してください。USR1 をトラップしない外側の bash スクリプトは、trapper が最後まで生き続ける間に強制終了されます。

ps -o %p%r%c -p$$スクリプトを挿入することで、各プロセスの PGID を確認できます。

$ /tmp/outer
  PID  PGID COMMAND
27630 27630 outer
  PID  PGID COMMAND
27633 27630 trapper
  PID  PGID COMMAND
27635 27630 usr1er
trapper: now killing usr1er
trapper: sleeping
usr1er: EXIT received, sending USR1
User defined signal 1
$ /tmp/trapper: line 9: 27635 Terminated              "$(dirname $0)"/usr1er
trapper: ignoring USR1
trapper: reached end of trapper
于 2014-02-20T13:09:08.933 に答える
0

この変更を試してください

/tmp/usr1er:

#!/bin/bash
trap 'echo "usr1er: EXIT received, sending USR1"; kill -USR1 $PPID' TERM
while sleep 1;do echo usr1er: sleeping;done

EXIT の代わりに TERM シグナルを処理し、代わりに USR1 を送信しまし$PPID0

于 2014-02-20T14:38:54.120 に答える