echo
SIGSTOP
または、信号が受信されたときに応答するスクリプトが提供されますSIGHUP
。
$cat test.sh
function clean_up {
echo "cleaning up!"
}
echo 'starting!'
trap clean_up SIGSTOP SIGHUP
sleep 100
私はそれをバックグラウンドで実行します:
$./test.sh > output &
[4] 42624
その後、-1
つまりを使って殺しました。ため息をつく
$kill -1 42624
しかし、trap
期待どおりに動作しません。つまり、output
ファイルに内容がありませんcleaning up!
。
$cat output
starting!
どうしたの?
答え1
これマニュアルページbash
状態
Bashがコマンドが完了するのを待ってトラップが確立されたことを知らせると、コマンドが完了するまでトラップは実行されません。
あなたの例では、trap
完了するまで実行されません。sleep 100
答え2
実際には印刷されますが、結果を見るには100秒待つ必要があります。
あなたは言う:
$./test.sh > output &
[4] 42624
確認すると、ps aux
次のような結果が表示されます。
xiaobai 42624 0.0 0.1 118788 5492 pts/3 S 04:07 0:00 /bin/bash
xiaobai 42626 0.0 0.0 108192 668 pts/3 S 04:07 0:00 sleep 100
デフォルトのスクリプトプロセス/bin/bash、PID 42624はまだスリープ100が完了するのを待っています。メインプロセスがシグナル1を受信しても、タスクをsleep 100
実行する前に完了するまで待つ必要がありますecho "cleaning up!"
。つまり、 。
睡眠プロセスをバックグラウンドプロセスにすることができます。この場合、スクリプトecho "cleaning up!"
プロセスが終了していない場合にのみ、スクリプトプロセスが待たずに実行される可能性があります。sleep process
次のスクリプトを使用して、概念(つまり、スクリプトがシグナルをsleep
処理する前に待機)を実演できます。
function clean_up {
echo "cleaning up!"
}
echo 'starting!'
trap clean_up SIGHUP
sleep 5000 &
echo 1
sleep 20
echo 2
sleep 10
echo 3
通常どおりこのスクリプトを実行し、./test.sh > output
PIDが23311であることをps aux
確認して実行します。また、このステップに注意してください。つまり、スクリプトがecho 1と入力するとsendを送信し、2が出るのを待ちます。その「整理」はすでに2に記載されています。以前一緒に印刷されました。最後にスクリプトを終了する順番です。/bin/bash
kill -1 23311
cat output
sleep 20
kill -1 23311
echo 3
$ cat output
starting!
1
cleaning up!
2
3
$
上記の実験は、スクリプトがSIGHUP信号を受信し、バックグラウンドプロセスを待たずに、前のすべての前景プロセスが完了した後にシグナルハンドラを実行することを証明しています。
話が面白くなるのに、元の台本でこうすればどうだろうかkill -1 PID_of_sleep_100
?
スリーププロセスは SIGHUP をスクリプトプロセスに返さないため、印刷せずにすべてのプロセスを終了します。
したがって、あなたの仕事のための解決策があります。kill -1 PPID
スクリプトプロセスのSIGHUPを承認するには、(スクリプトプロセス)を実行してからkill -1 PID
(休止プロセス)を実行できます.スクリプトプロセスは終了前にSIGHUPハンドラを実行します。楽しいハッキングになりますように:)
すべての信号が同じというわけではありません。SIGKILLはトラップを許可しません。。 -9スクリプトプロセスを終了すると、スリーププロセスは引き続き実行され、対応する親PIDは1になります(検査に合格ps -ef
)。
[修正する]:
一般的にkill -N script_PID
そうです。信号 N がスクリプトに取り込まれない場合は、単にスクリプトを終了します。。ただし、SIGINTに注意してください。kill -2 script_PID
スクリプトがそれをキャプチャできなくても、直接終了するわけではありません。スクリプトは、子プロセス(sleep 10など)が完了するのを待ちます。ここで、script_PIDで複数のシャットダウン(kill -2 script_PID
ANDなど)を実行するとしますkill -user-defined_trap_N script_PID
。
- 寝ていると10秒待ってから正常に戻ります。または2以外の信号で死亡、スクリプトは返されたときにキャッシュされた信号2を無視し、カスタム_trap_N関数を実行します。
- しかし寝るとシグナル2キルすると、スクリプトは戻り時に組み込みSIGINTハンドラを実行し、user-define_trap_Nを実行せずに直接終了します。