シェルスクリプトで実行したときにsleepがSIGINTを無視するのはなぜですか?

シェルスクリプトで実行したときにsleepがSIGINTを無視するのはなぜですか?

sleep手動で実行すると、kill -INTスリープはすぐに終了します。たとえば、

$  /bin/sleep  60  &
[1] 4002356
$  kill -INT 4002356
[1]+  Interrupt               /bin/sleep 60
$  ps -C sleep
    PID TTY          TIME CMD
$  

ただし、シェルスクリプトで同じことを行うとsleep無視されますSIGINT。たとえば、次のようになります。

set  -o xtrace

echo
/bin/sleep  10  &
child="$!"
/bin/sleep  0.1
ps -C sleep
kill  -TERM  "$child"    #  SIGTERM                                         
/bin/sleep  0.1
ps -C sleep
wait  "$child"    #  will return immediately                                

echo
/bin/sleep  10  &
child="$!"
/bin/sleep  0.1
ps -C sleep
kill  -INT  "$child"    #  SIGINT
/bin/sleep  0.1
ps -C sleep
wait  "$child"    #  will wait for 9.8 seconds                              

SIGINTsleepシェルスクリプトで睡眠を実行すると、なぜ/どのように睡眠が無視されますか?

dash私はと同じ動作をしますbash。私のカーネルはLinux 5.4.0です。

ベストアンサー1

/bin/sleep 10 &終了時に&シェルがsleep非同期的に実行されるようにします。デフォルトでは、ジョブ制御はスクリプトで無効になっています。 Bashでは、以下が適用されます。

Bashによって実行される非組み込みコマンドは、シグナルハンドラをシェルが親から継承した値に設定します。ジョブ制御が非アクティブの場合、非同期コマンドはSIGINTを無視します。これらの継承されたハンドラに加えて、SIGQUITがあります。

源泉:バッシュリファレンスマニュアル

関連して、SIG_IGNペアの呼び出し全体で持続しますが、execv()例外が存在する可能性がありますSIGCHLD

呼び出しプロセスイメージでデフォルトアクション(SIG_DFL)に設定されている信号は、新しいプロセスイメージでもデフォルトアクションに設定する必要があります。 SIGCHLDに加えて、呼び出しプロセスイメージが無視されるように設定された信号(SIG_IGN)も、新しいプロセスイメージによって無視されるように設定する必要があります。呼び出しプロセスイメージによってキャプチャされるように設定された信号は、新しいプロセスイメージでデフォルトアクションに設定する必要があります(<signal.h>を参照)。

源泉:Open Group 基本仕様 2018年7号版

おすすめ記事