bash
Kubuntu Trusty 64ビットで4.3を実行します。次の2つの記事を参照してください。
Trapatint.sh
#! /bin/bash
trap "echo Exiting" INT
cat </dev/urandom >/dev/null
echo Hello
Captureexit.sh
#! /bin/bash
trap "echo Exiting" EXIT
cat </dev/urandom >/dev/null
echo Hello
^ Cを押すとSIGINTをキャッチすると両方が印刷され、EXITをキャッチすると印刷されExiting
ますが、追加の改行が含まれます。Hello
Exiting
$ ./trapping-int
^CExiting
Hello
$ ./trapping-exit
^CExiting
$
他の動作の理由を知りたいです。また、^ CにINTが提供されてもEXITが常に呼び出されると安全に仮定できますか?
両方のスクリプトで最後の行をコメントアウトすると、SIGINTをキャプチャするとHelloが印刷されなくなりますが、EXITをキャプチャするとまだ改行が印刷されます。ここの理由も知りたいです。
ありがとうございます!
ベストアンサー1
まず、シグナルとシェルに関するいくつかの事実を要約します。
キーボードでCTRL + Cを押すと、前景プロセスのプロセスグループ内のすべてのプロセスにSIGINTが送信されます。この場合、スクリプトを解釈する
cat
コマンドとbash
プロセスの両方がSIGINTを受け取ることを意味します。をトラップするときにハンドラが明示的に終了しない限り、プロセスは終了しません
INT
。INT
をトラップすると、引数
EXIT
は特定の信号で実行されず、シェルが終了したときに実行されます。
trapping-int.sh
これらの事実を考慮すると、次のようなことが発生することがわかっているので、の動作は簡単です。
- プロセスは
cat
SIGINT を受け取り、実行を終了します。 - プロセス
bash
はSIGINTを受け取り、シグナルハンドラを実行して「Exiting \ n」をに印刷しますSTDOUT
。 - プロセス
bash
は実行を続行し、「Hello \ n」をに印刷しますSTDOUT
。 bash
スクリプトの終わりに達するとプロセスは終了します。
動作trapping-exit.sh
もほとんど簡単です。
- プロセスは
cat
SIGINT を受け取り、実行を終了します。 - プロセス
bash
はSIGINTを受け取り、シグナルハンドラがないため終了します。echo
シグナルを受信した直後に終了するため、コマンドは実行/実行されません。 bash
プロセスが終了しているため、ハンドラが実行され、EXIT
「Exiting \ n」がに印刷されますSTDOUT
。
残りの質問は「改行文字はどこから来るのか」です。私はバッシュ自体がSIGINT
改行文字を印刷するハンドラをインストールしていると思います。
スクリプトでtrapping-int.sh
Bash のハンドラをオーバーライドしてSIGINT
追加の改行を取得しません。