いくつかの補助スクリプトを制御する基本スクリプトがあります。端末から割り込み信号を送信すると、親は信号をtrap
キャッチしましたが、子はキャッチできず、その理由を理解できません。デフォルトの端末設定を変更していません(stty
どこでも実行しません)。
私の親とサブスクリプトと端末出力は次のとおりです。
親:
#!/bin/sh
./child.sh &
for sig in $(kill -l) ; do
trap "echo parent:$sig" $sig
done
wait
子供:
#!/bin/sh
cat < /dev/tty &
PID=$!
for sig in $(kill -l) ; do
trap "echo child:$sig" $sig
done
wait
ターミナルインタラクション:
[prompt]$ ./parent.sh
^Cparent:INT
cat: stdin: Input/output error
[prompt]$
修正する
macOSとCentOSでスクリプトをテストしましたが、上記の動作が発生しました。デフォルトのBourne互換シェルを使用してFreeBSDでこれをテストするときに子プロセスが受け取る信号はCHLD
。
答え1
非対話型シェルで非同期に実行されるコマンドの場合(実際にジョブ制御が有効になっていない場合)、POSIXコンプライアンスではSIGINTとSIGQUITは無視されます。sh
POSIXの要件一部のシェルはこれを無視しますが。
別のPOSIX要件問題は、シェルの起動時にシグナルが無視された場合は無視できないため、壊れることです。
ここでは、迷惑な「機能」(少なくとも現在のバージョンでは)のない機能を代わりに使用できますzsh
。sh
それにもかかわらず、シェルでの信号処理は、信頼性が最も低く、移植性が劣る側面の1つです。動作は、シェルごとに、同じシェルの異なるバージョン間で大きく異なることがわかります。普通でないことを試してみたい場合は、深刻な引っ張りと頭の傷を経験する準備をしてください。
何が起こるかをよりよく制御できるように、他の言語を使用することをお勧めします。
また、可能なすべての信号を盲目的に処理せずに受信することを期待し、処理方法を知っている信号のみを処理します。たとえば、SIGCHLD(プロセスを作成してシャットダウンを処理する操作なので、シェル自体に興味がある)をキャプチャすると、必要に応じて機能しない可能性があります。