bashスクリプトでSIGQUITを適切にトラップするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/6381353

質問

SIGINTをうまくトラップするシェルスクリプトを書くことはできますが、SIGQUITをトラップできないようです。 ジェネラコディセタグプレ

このスクリプトを実行してCTRL-Cを押すと目的の効果が得られますが、CTRL-\を押すと(私が理解しているように、SIGQUITがトリガーされます)、ターミナルに^\を出力する以外は何もしません。なぜですか?

私には2つの実行理論があります。 1つ目は、SIGINTSIGQUITのセマンティクスが異なるため、SIGQUITは子プロセスsleepにのみ送信され、SIGINTは子プロセスと親bashプロセスの両方に送信されます。この場合、どこに文書化されていますか?

私の2番目の理論は、bashはデフォルトでSIGQUITを無視する(つまり、no-opハンドラーを持っている)だけでなく(manページが示唆しているように)、トラップをまったく許可しないというものです。この理論は最初の理論と重複しています。これは、SIGQUITが親と子の両方に送信される可能性があるためですが、親(bash)はそれをトラップできません。この場合、bashスクリプトでSIGQUITをトラップする方法はありますか?...おそらく設定できるshoptがありますか?

編集:これは、bash4.1.5を実行しているgnome-terminal2.32.0のUbuntu10.10にあり、はい、^\はSIGQUITを発行するように構成されています(stty -aによって報告され、^\ SIGQUITをpingなどの他のプログラムに発行することで確認されます)。

更新: 問題はどういうわけかgnome-terminalに起因しているに違いないことを発見しました。このスクリプトを仮想コンソールから実行すると(つまり、ctrl-alt-f1を実行してXから抜け出す)、^\を押すと、SIGQUITが完全にトラップされます。同じbashとすべてなので、唯一の違いはターミナルエミュレーターでなければなりません。だから今私の質問は次のようになります:この点で仮想コンソールのように動作するようにgnome-terminalを構成するにはどうすればよいですか?私は仮想コンソールとgnome-terminalでdiffの出力をジェネラコディセタグコードしました。違いはありますが、すぐに関連するものは何もないようです(たとえば、両方にジェネラコディセタグコードがあります)。

更新2: 別の実験。 gnome-terminalでstty -aを実行するだけです。 quit = ^\;を押すと、信号がキャッチされなくなります。次に、仮想コンソールで$ sleep 60を実行します。 ^\を押すと、シグナルがキャッチされます。プロセスは$ sleep 60を出力して終了します。しかし、今度はgnome-terminalで^\を実行し、Quitを押します。信号は期待どおりにキャッチされて処理されます。そのため、仮想コンソールから呼び出されたときに他のプログラムがSIGQUITをキャッチしたとしても、他のプログラムはSIGQUITをキャッチできないなど、gnome-terminalには奇妙なことがあります。おそらく、gnome-terminalをアップグレードする必要があります。

役に立ちましたか?

解決

これはgnome-terminal2.32.0のある種のバグであるとしか思えません。その後、gnome-terminal2.32.1(およびbash 4.2.8)を使用してUbuntu 11.04にアップグレードしましたが、SIGQUITは期待どおりにトラップされています。

他のヒント

XFCEを使用したFedora19でも同じ動作が見られます。ps sによると、xfce4ターミナルのbashではSIGQUITが無視され、yes >/dev/null &が実行され、ps sは、サブプロセスでもSIGQUITが無視されていることを示しています。(同じ端末から)ssh localhostを実行すると、sshセッションのシェルでもSIGQUITが無視されますが、yes >/dev/null &では無視されません。

gnome-terminalについて言及している上記のコメントを考えると、バグは2つの端末の共通部分であるvteライブラリにあると思います。私のはvte-0.28.2-9.fc19.x86_64です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top