EXITキャッチがINTとは異なる動作をする理由

EXITキャッチがINTとは異なる動作をする理由

bashKubuntu 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ますが、追加の改行が含まれます。HelloExiting

$ ./trapping-int 
^CExiting
Hello
$ ./trapping-exit 
^CExiting

$

他の動作の理由を知りたいです。また、^ CにINTが提供されてもEXITが常に呼び出されると安全に仮定できますか?

両方のスクリプトで最後の行をコメントアウトすると、SIGINTをキャプチャするとHelloが印刷されなくなりますが、EXITをキャプチャするとまだ改行が印刷されます。ここの理由も知りたいです。

ありがとうございます!

ベストアンサー1

まず、シグナルとシェルに関するいくつかの事実を要約します。

  • キーボードでCTRL + Cを押すと、前景プロセスのプロセスグループ内のすべてのプロセスにSIGINTが送信されます。この場合、スクリプトを解釈するcatコマンドとbashプロセスの両方がSIGINTを受け取ることを意味します。

  • をトラップするときにハンドラが明示的に終了しない限り、プロセスは終了しませんINTINT

  • をトラップすると、引数EXITは特定の信号で実行されず、シェルが終了したときに実行されます。

trapping-int.shこれらの事実を考慮すると、次のようなことが発生することがわかっているので、の動作は簡単です。

  • プロセスはcatSIGINT を受け取り、実行を終了します。
  • プロセスbashはSIGINTを受け取り、シグナルハンドラを実行して「Exiting \ n」をに印刷しますSTDOUT
  • プロセスbashは実行を続行し、「Hello \ n」をに印刷しますSTDOUT
  • bashスクリプトの終わりに達するとプロセスは終了します。

動作trapping-exit.shもほとんど簡単です。

  • プロセスはcatSIGINT を受け取り、実行を終了します。
  • プロセスbashはSIGINTを受け取り、シグナルハンドラがないため終了します。echoシグナルを受信した直後に終了するため、コマンドは実行/実行されません。
  • bashプロセスが終了しているため、ハンドラが実行され、EXIT「Exiting \ n」がに印刷されますSTDOUT

残りの質問は「改行文字はどこから来るのか」です。私はバッシュ自体がSIGINT改行文字を印刷するハンドラをインストールしていると思います。

スクリプトでtrapping-int.shBash のハンドラをオーバーライドしてSIGINT追加の改行を取得しません。

おすすめ記事