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
SIGINT
sleep
シェルスクリプトで睡眠を実行すると、なぜ/どのように睡眠が無視されますか?
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>を参照)。