web-dev-qa-db-ja.com

bashの否認はどのように機能しますか?

Linuxシステムでは、bash組み込みコマンドdisownを使用して、現在のセッションからジョブを削除できます。 bashはこの機能をどのように実装しますか?ここではsetsid()が使用されていますか?使用されている場合、bashはどのようにして子プロセスをトリガーしてsetsid()を呼び出しますか?信号を使用していますか?

1
Wenlin.Wu

いいえ。disownnot現在のセッションからジョブを削除し[1]、端末からジョブを切り離さず、セッション時にカーネルがジョブを送信する信号に影響を与えません。リーダーが終了するか、制御端末が取り壊されたとき。

disownは、bash自身のジョブテーブルでのみ機能し、bashが制御しているジョブの概念のみを変更し、bash自体の動作、つまり、bashが受信したSIGHUPを再送信するジョブにのみ影響します。処理する。そのSIGHUP再送信は、bash [2]の追加機能であり、標準では必要なく、OSによって提供されるジョブ制御とは関係ありません。

簡単な例でそれを見ることができます。ここでは、script(1)を使用して、ptyとその中で実行されるインタラクティブなシェルセッションを作成しています。

$ script /dev/null -qc bash
$ sh -c 'sleep 555 & sleep .1; kill -STOP $!; trap "echo hupped!" HUP; sleep 666' &
[1] 3837
$ disown -a
$ jobs
   # no jobs known to bash
$ pgrep -as0
   # show all processes from the current session
3836 bash
3837 sh -c sleep 555 & sleep .1; kill -STOP $!; trap "echo hupped!" HUP; sleep 666
3838 sleep 555
3841 sleep 666
$ kill -HUP $$
   # seppuku the session leader
Hangup
hupped!

ここで、カーネルはSIGHUPシグナルをバックグラウンドプロセスグループ(=ジョブ)に送信します。これは、そのプロセスの1つが停止しているためです。また、カーネルの所有権を剥奪してもnotそれが起こらないようにします。

sh -c '...'のすべてのプロセスは、「バックグラウンド」sleep &を含め、同じジョブの一部です。シェルスクリプトは、デフォルトではジョブ制御を行いません。

バックグラウンドプロセスグループのメンバーが停止していない場合、SIGHUPは送信されません。

$ script /dev/null -qc bash
$ sh -c 'sleep 555 & trap "echo hupped!" HUP; sleep 666' &
[1] 3270
$ disown -a
$ kill -HUP $$
    # sleep 555, 666 and sh -c are still running

最後に、bashがセッションリーダーであるかどうか、またはジョブが実行中、停止中かどうかに関係なく、bashはテーブルからすべてのジョブ(それ自体で開始され、所有権を剥奪されていないジョブのみ)にSIGHUPを送信します。等:

$ bash
$ sh -c 'sleep 555 & trap "echo hupped!" HUP; sleep 666' &
[1] 3413
$ kill -HUP $$
Hangup
hupped!
Hangup

[1]とにかく行うことは不可能です。 setsid()は、notプロセスグループリーダーであるプロセスのみを新しいセッションにすることができます。移動する方法はありません。新規または既存のセッションへのジョブ全体。

[2]これはbashのマンページに記載されています:

シェルは、SIGHUPを受信するとデフォルトで終了します。終了する前に、対話型シェルは実行中または停止中のすべてのジョブにSIGHUPを再送信します。停止したジョブはSIGCONTに送信され、SIGHUPを確実に受信します。シェルが特定のジョブにシグナルを送信しないようにするには、disownが組み込まれているジョブテーブルから削除するか(以下のシェルビルドコマンドを参照)、disown -hを使用してSIGHUPを受信しないようにマークする必要があります。 。

loginbashシェルが終了時にジョブにHUPを送信する原因となるshopt -s huponexitもあります(シグナルのためかどうかは関係ありません)。 )、これもOSの標準のジョブ制御機能と紛らわしい方法で重複しています。

1
mosvy