説明してください:
#!/bin/bash
# This is scripta.sh
./scriptb.sh &
pid=$!
echo $pid started
sleep 3
while true
do
kill -SIGINT $pid
echo scripta.sh $$
sleep 3
done
-
#!/bin/bash
# This is scriptb.sh
trap "echo Ouch;" SIGINT
while true
do
echo scriptb.sh $$
sleep 1
done
トラップを実行すると./scripta.sh
印刷されません。 SIGINTから別の信号に切り替えると(SIGTERM、SIGUSR1を試しました)、トラップは期待どおりに「Ouch」を印刷します。どうすればこれが起こりますか?
ベストアンサー1
SIGINTから別の信号に切り替えると(SIGTERM、SIGUSR1を試しました)、トラップは期待どおりに「Ouch」を印刷します。
明らかにSIGQUITを試していない場合は、SIGINTと同じように動作することがわかります。
問題は業務管理だ。
Unixの初期には、シェルがプロセスまたはパイプをバックグラウンドに入れるたびに、そのプロセスがSIGINTとSIGQUITを無視するように設定したため、ユーザーがCtrl+ C(中断)またはCtrl+(終了)を入力しても\プロセスは終了しませんでした。 。前景の仕事。タスク制御が登場したときにプロセスグループも一緒にインポートされたので、シェルでやるべきことは、バックグラウンドタスクを現在のターミナルプロセスグループでない限り新しいプロセスグループに入れることです。キーボードの入力(Ctrl+ C、Ctrl+ \ 、Ctrl+ Z(SIGTSTP))。シェルを使用すると、バックグラウンドプロセスが基本的な信号処理を維持できます。実際には、プロセスが前景Ctrlに出てくるときに+終了する必要があるかもしれません。C
ただし、非対話型シェルはジョブ制御を使用しません。歴史的な理由から、非対話型シェルはバックグラウンドプロセスに対してSIGINTとSIGQUITを無視する以前の動作に戻り、キーボードタイプの信号が送信されてもバックグラウンドプロセスを実行し続けることが合理的です。シェルスクリプトは非対話型シェルで実行されます。
trap
そして、命令の下の最後の段落を見ると大きな打撃(1)、あなたは見るでしょう
シェルに入ると無視される信号はキャプチャまたはリセットできません。
./scriptb.sh &
だからあなたから逃げたらインタラクティブシェルのコマンドプロンプトでは、対応する信号設定は変更されず(バックグラウンドに配置されていても)コマンドは期待どおりにtrap
機能します。ただし./scripta.sh
、(使用するかどうかにかかわらず)実行すると、&
非対話型シェルでスクリプトが実行されます。非対話型シェルが実行されると、割り込みを無視して終了するようにプロセスを設定します./scriptb.sh &
。scriptb
したがって、コマンドはtrap
自動的にscriptb.sh
失敗します。