web-dev-qa-db-ja.com

SIGTERMがbashを終了するように機能するのに、ashやdashを終了しないのはなぜですか?

bashash、およびdashを比較すると、bashのみがSIGTERMで終了できます。

kill -TERM <pid>

ashおよびbashの場合、SIGHUPまたはSIGKILLが必要です

kill -HUP <pid>
kill -KILL <pid>

これの背後にある理由は何ですか?さらに、動作はシステムに依存しているようです。

  • bashは、Ubuntu 14.04 Trusty、Ubuntu 16.04 Xenial、Ubuntu 18.04 Bionic、Ubuntu 19.10 Eoan、Ubuntu 20.04 Focal、Debian 8 Jessie、Debian 9 Stretch、Debian 10 Buster、CentOS8ではSIGTERMで終了します。
  • bash is not終端はSIGTERMでCentOS 6、CentOS 7
2
finefoot

これは私には予想外でしたが、いくつかのビルドを実行すると、bash 4.0ではなくgitからのbashの最新コードで再現可能であることが明らかになりました。そのため、git bisectは、次のコミットを責任があるものとして特定するのに役立ちました。

% git bisect good                     
ac50fbac377e32b98d2de396f016ea81e8ee9961 is the first bad commit
commit ac50fbac377e32b98d2de396f016ea81e8ee9961
Author: Chet Ramey <[email protected]>
Date:   Wed Feb 26 09:36:43 2014 -0500

    Bash-4.3 distribution sources and documentation

Bashの個々のgitコミットはかなり大きく、スコープがそれほど厳密ではない傾向がありますが、そのコミットを数分かけて実行すると、SIGTERMがバイパスすることになっている新しいrl_signal_event_hookなど、readlineがSIGTERMを処理する方法に多くの変更が加えられています。 SIGTERMをチェックし、termsig_handlerを呼び出す場所。

これらの変更の一部は、変更ログの次の新しいエントリと一致します。

Readlineは、入力の読み取り中にシグナルを取得した後、アプリケーションが設定したイベントフック(rl_signal_event_hook)を呼び出し(readは-1/EINTRを返しますが、readlineはシグナルをすぐには処理しません)、アプリケーションが処理できるようにします。現在、SIGHUPまたはSIGTERMでは呼び出されません。

このメッセージから判断すると、行動の変化は意図的なものではないのではないかと思います。

これが意図的であったかどうかの根底に到達することを期待して、このスレッドをバグバッシュメーリングリストに転送します。

3
Chris Down

これは、bashがreadline行編集ライブラリを使用している場合、およびbashがユーザーからの入力を待機している場合にのみ発生します。

_bash --noediting_はSIGTERMによって強制終了されません。また、_kill -TERM $$_を実行している場合、bashはそれ自体を強制終了しません。

これは、bashがユーザーからの入力を取得するために使用するreadline()関数が、SIGTERM用の独自のシグナルハンドラーをインストールし、戻る前に元のシグナル処理を復元するために発生します。 SIGTERMがユーザーからの入力を待っている間にreadlineが発生した場合、readline()NULLを返します。

readline()yy_readline_get())を呼び出すbash関数は、NULLの戻りをEOFとして解釈し、シェルを終了します。このシナリオは、この answer のシナリオと非常に似ています。

これは、SIGTERM ;-)を設定することで、インタラクティブなbashをIGNOREEOFで存続させることもできることを意味します。

_$ bash
$ IGNOREEOF=10
$ echo $$
11096
<kill -TERM 11096 from another terminal>
$ Use "exit" to leave the Shell.
<kill -TERM 11096 from another terminal>
$ Use "exit" to leave the Shell.
...
<the 10th will get it>
$ exit
$
_
3
mosvy