うまくトラップするシェルスクリプトを書くことはできますが、トラップ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つの実行理論があります。SIGINT1つ目は、とのセマンティクスSIGQUITが異なり、子プロセスにSIGQUITのみ送信され、子プロセスと親bashプロセスの両方に送信されることです。この場合、どこに文書化されていますか?sleepSIGINT
私の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-f1Xから抜け出すために)、を押すとSIGQUITが完全にトラップされ^\ます。同じbashとすべてなので、唯一の違いはターミナルエミュレーターでなければなりません。だから今私の質問は次のようになります:この点で仮想コンソールのように動作するようにgnome-terminalを構成するにはどうすればよいですか?仮想コンソールとgnome-terminalでdiffの出力をstty -a確認しました。違いはありますが、すぐに関連するものはないようです(たとえば、両方にquit = ^\;)。
更新2:別の実験。$ sleep 60gnome-terminalで実行するだけです。を押す^\と、信号がキャッチされなくなります。$ sleep 60次に、仮想コンソールで実行します。を押す^\と、シグナルがキャッチされます。プロセスは印刷Quitされて終了します。しかし、今度$ ping google.comはgnome-terminalで実行し、^\-を押します。信号がキャッチされ、期待どおりに処理されます。したがって、仮想コンソールから呼び出されたときに他のプログラムがSIGQUITをキャッチしたとしても、SIGQUITは一部のプログラムではキャッチできるが、他のプログラムではキャッチできないなど、gnome-terminalには奇妙なことがあります。おそらく、gnome-terminalをアップグレードする必要があります。