うまくトラップするシェルスクリプトを書くことはできますが、トラップSIGINT
できないようですSIGQUIT
。
#!/bin/bash
function die {
echo "Dying on signal $1"
exit 0
}
trap 'die "SIGINT"' SIGINT
trap 'die "SIGQUIT"' SIGQUIT
while true; do
echo "sleeping..."
sleep 5
done
このスクリプトを実行して押すとCTRL-C
目的の効果が得られますが、押すCTRL-\
と(私が理解しているように、トリガーされるはずです) 、ターミナルでのSIGQUIT
印刷以外は何もしません。^\
なんで?
私には2つの実行理論があります。SIGINT
1つ目は、とのセマンティクスSIGQUIT
が異なり、子プロセスにSIGQUIT
のみ送信され、子プロセスと親bashプロセスの両方に送信されることです。この場合、どこに文書化されていますか?sleep
SIGINT
私の2番目の理論は、bashはデフォルトで(manページが示唆しているように)無視する(つまり、no-opハンドラーを持っているSIGQUIT
)だけでなく、トラップされることをまったく許可しないというものです。この理論は最初の理論と重複しています。これはSIGQUIT
、親と子の両方に当てはまる可能性があるためですが、親(bash
)はそれをトラップできません。この場合、 bashスクリプトをトラップする方法はありますSIGQUIT
か?...おそらくshopt
私が設定できるものはありますか?
編集:これは、bash4.1.5を実行しているgnome-terminal2.32.0のUbuntu10.10にあり、yesはSIGQUITを発行するように構成されています(SIGQUITを他のプログラムに発行すること^\
で報告stty -a
および確認されています)。^\
ping
更新:問題はどういうわけかgnome-terminalに起因しているに違いないことを発見しました。このスクリプトを仮想コンソールから実行すると(つまり、ctrl-alt-f1
Xから抜け出すために)、を押すとSIGQUITが完全にトラップされ^\
ます。同じbashとすべてなので、唯一の違いはターミナルエミュレーターでなければなりません。だから今私の質問は次のようになります:この点で仮想コンソールのように動作するようにgnome-terminalを構成するにはどうすればよいですか?仮想コンソールとgnome-terminalでdiff
の出力をstty -a
確認しました。違いはありますが、すぐに関連するものはないようです(たとえば、両方にquit = ^\;
)。
更新2:別の実験。$ sleep 60
gnome-terminalで実行するだけです。を押す^\
と、信号がキャッチされなくなります。$ sleep 60
次に、仮想コンソールで実行します。を押す^\
と、シグナルがキャッチされます。プロセスは印刷Quit
されて終了します。しかし、今度$ ping google.com
はgnome-terminalで実行し、^\
-を押します。信号がキャッチされ、期待どおりに処理されます。したがって、仮想コンソールから呼び出されたときに他のプログラムがSIGQUITをキャッチしたとしても、SIGQUITは一部のプログラムではキャッチできるが、他のプログラムではキャッチできないなど、gnome-terminalには奇妙なことがあります。おそらく、gnome-terminalをアップグレードする必要があります。