簡単な要約:親と子はループ内にあり、それぞれ信号をキャプチャすることも、キャプチャすることもできません。子供は問題があり、親は問題がないのに、なぜ親は解雇されないのか理解できません。
詳細:
ループを実行し、オプションでSIGINTやその他の信号をキャプチャする2つの簡単なスクリプトがあります。サブスクリプトは親スクリプトによって開始されます。
親:
#!/bin/bash
parent_trap=$1
child_trap=$2
shutdown=0
(( parent_trap )) && trap "echo 'parent: caught signal'; shutdown=1" INT TERM HUP PIPE
while (( ! shutdown )) ; do
echo parent
./child $child_trap
sleep 1
done
子供:
#!/bin/bash
child_trap=$1
shutdown=0
(( child_trap )) && trap "echo 'child: caught signal'; shutdown=1" INT TERM HUP PIPE
while (( ! shutdown )) ; do
echo child
sleep 1
done
これが4つの捕捉信号の組み合わせで実行される場合:
トラップなし:
$ ./parent 0 0
parent
child
child
child
^C
親プロセスと子プロセスの両方が ctrl-c で終了します。私が理解したように、シェルはハンドラなしでプロセスグループ内のすべてのプロセスにSIGINTを送信し、デフォルトのアクションであるシャットダウンを呼び出します。
両親と子供の両方が困難に直面しています。
$ ./parent 1 1
parent
child
child
child
^Cchild: caught signal
parent: caught signal
両親と子の両方が信号を受け取り、両方ともきれいに退場します。
親はシグナルを捉えますが、子供は次のことを行いません。
$ ./parent 1 0
parent
child
child
child
^Cparent: caught signal
親プロセスは信号を捕捉し、きちんと終了します。その子は解雇のために殺された。 (私の考えでは)
子プロセスはシグナルをキャプチャし、親プロセスはシグナルをキャプチャしません。
$ ./parent 0 1
parent
child
child
child
^Cchild: caught signal
parent
child
^Cchild: caught signal
parent
child
^Cchild: caught signal
^C
子プロセスはシグナルをキャッチしてきちんと終了しますが、シグナルをキャッチしなかった親プロセスはctrl-cをすばやく2回押すまで続きます(サブプロセスを再開します)。
シグナルハンドラがないときに親がデフォルトタスクで終了しないのはなぜですか?