ログアウト時にSIGHUPがジョブに送信されない場合は何ですか?

ログアウト時にSIGHUPがジョブに送信されない場合は何ですか?

実行中であると主張するユーザーの回答を読みました。

foo 2>&1 >& output.log &

fooログオフしても引き続き実行されます。ユーザーによると、SSH接続を介してもこれを行うことができます。

SSHを切断したりTTYを終了したりすると、シェルとそのプロセスがSIGHUPを受信して​​終了するという印象を受けたので、私は本当に信じていません。私の仮定によると、これがこの場合orなどをnohup使用する唯一の理由ですtmuxscreen

それから調査しました。glibc マニュアル:

このシグナルは、セッションに関連する操作に端末の制御プロセスの終了を報告するためにも使用されます。このシャットダウンは、制御端末からセッション内のすべてのプロセスを効果的に切断します。

これが私の考えを確証してくれるようだ。しかし、もう少し詳しく見てみると、それは言う:

プロセスが制御端末のセッションリーダーの場合、SIGHUP信号はフォアグラウンドジョブの各プロセスに送信され、制御端末はセッションから切断されます。

もしそうなら、これはバックグラウンドに置かれた仕事ですいいえSIGHUPを受けましたか?

私をより混乱させるために、インタラクティブなZshセッションを実行、実行、yes >& /dev/null &入力していますexit。この時点で、Zshはジョブを実行中であると警告し、exit2回目の入力後にジョブがSIGHUPdになったと言いました。 Bashで同じことを行うと、ジョブは引き続き実行されます。

答え1

BashはSIGHUP受信時にのみ送信されるようですSIGHUP。これは、たとえば、仮想端末が閉じられたとき、またはSSH接続が中断されたときに発生する可能性があります。 ~から文書:

デフォルトでは、シェルはSIGHUPを受信した後に終了します。対話型シェルは、シャットダウン前に実行中または停止したすべてのジョブにSIGHUPを再送信します。停止したジョブは、SIGHUPを受信できるようにSIGCONTに送信されます。シェルが特定のジョブにSIGHUP信号を送信しないようにするには、disown組み込み関数を使用してジョブテーブルからその信号を削除するか(タスク制御組み込み関数を参照)、disown -hを使用して受信しないようにマークします。ため息。

したがって、+を入力exitまたは押すと、Bashにハング信号を送信しないため、すべてのバックグラウンドプロセスが維持されます。CtrlD

Bashにまだ実行中のバックグラウンドプロセスがあることを警告するように強制できます。

shopt -s checkjobs

SIGHUP対話型シェルにいる場合は、終了時にメッセージを送信することを選択できます(ねえ)。しかし、私のBash 4.2.25システムでは動作しません。たぶんあなたに似合うかもしれません。

shopt -s huponexit

関連情報