シェルが終了したときにバックグラウンドジョブが強制終了されるか、強制終了されるかを正確に決定するものは何ですか?


12

この質問は非常 多く本当に たくさん)出てきまし、答えは一般的に不完全であると思います。一般的な質問は、「sshを終了/殺すと、なぜ私の仕事は殺されないのですか?」であり、これが私が見つけたものです。最初の質問は次のとおりです。次の情報はどの程度一般的ですか?以下は最近のDebian linuxに当てはまるようですが、少し欠けています。そして、他の人は何を知る必要がありますか?

  1. バックグラウンドまたはssh接続で開かれたシェルのすべての子プロセスは、オプションが設定されている場合のみ ssh接続が閉じられたときにSIGHUPで強制終了されます。huponexitshopt huponexit

  2. 場合はhuponexittrueで、あなたは使用することができますnohupまたはdisownあなたが終了したときに、それは殺さないようにシェルからプロセスを解離します。または、で実行しscreenます。

  3. 少なくとも一部のLinuxでデフォルトhuponexitであるfalseの場合、通常のログアウトでバックグラウンドジョブは強制終了されません

  4. しかし、場合でも、huponexitSSH接続を取得し、その後場合は、falseで殺され、または(通常のログアウトとは異なる)に低下し、バックグラウンドにプロセスがまだ殺されてしまいます。これは(2)によって、disownまたはnohup(2)のように回避できます。

  5. (a)親プロセスが端末であるプロセスと(b)端末にstdin、stdout、またはstderrが接続されているプロセスにはいくつかの違いがあります。(a)でないプロセス(b)、またはその逆のプロセスに何が起こるかわかりません。

最後の質問:行動を回避するにはどうすればよいですか(3)?言い換えると、Debianのデフォルトでは、バックグラウンドプロセスはログアウト後は単独で実行されますが、ssh接続が切断された後は実行されません。接続が正常に閉じられたか、終了されたかに関係なく、プロセスに同じことが起こることを望みます。または、これは悪い考えですか?

編集:ジョブを強制終了する別の重要な方法は、どちらの場合でも機能しますか(?)、screenを介して実行することです。しかし、質問は、物事が殺されるときとそうでないときを理解することに関するものです。例えば、時々、人々はログアウト時にジョブを殺したいことがあります。

ほかのスレッド: - シグナル(SIGHUP)、仕事上の明確化、および制御端末 - /server/117152/do-background-processes-get-a-sighup-when-logging-offは - 続行SSHバックグラウンドタスク/ジョブSSHを閉じる - SSHセッションが閉じられた後にバックグラウンドでジョブプットは実行し続けますか? - 防止SSHクライアントを閉じた後に停止されてから、すでに実行中のバックグラウンド・プロセス - どのように私はそれが私の切断後に実行し続けることが、このようなSSH経由でプロセスを開始することができますか? - OS X上で実行しているリモート・ジョブを維持することができません - 閉じるSSH接続

回答:


1

プロセスは「SIGHUPで殺される」わけではありません-少なくとも、厳密な意味ではありません。むしろ、接続が切断されると、端末の制御プロセス(この場合はBash)にハングアップ信号*が送信されます。これは通常、「HUP信号」または単にSIGHUPと略されます。

これで、プロセスがシグナルを受信すると、必要に応じて処理できます**。ほとんどのシグナル(HUPを含む)のデフォルトでは、すぐに終了します。ただし、プログラムは代わりにシグナルを自由に無視したり、何らかのシグナルハンドラー関数を実行したりすることもできます。

Bashは最後のオプションを選択します。HUPシグナルハンドラは、「huponexit」オプションがtrueであるかどうかを確認し、trueの場合、SIGHUPを各子プロセスに送信します。それが終了すると、Bashは終了します。

同様に、各子プロセスは、シグナルを受信したときに自由に実行できます。デフォルトに設定したままにする(つまりすぐに終了する)か、無視するか、シグナルハンドラを実行します。

Nohupは、子プロセスのデフォルトアクションを「無視」に変更するだけです。ただし、子プロセスが実行されると、シグナルに対する独自の応答を自由に変更できます。

これは、あなたがnohupで実行したにもかかわらず、いくつかのプログラムが死ぬ理由で​​す。

  1. Nohupはデフォルトのアクションを「無視」に設定します。
  2. プログラムは、終了時に何らかのクリーンアップを行う必要があるため、SIGHUPハンドラーをインストールし、「無視」フラグを偶然上書きします。
  3. SIGHUPが到着すると、ハンドラーが実行され、プログラムのデータファイル(または必要なもの)がクリーンアップされ、プログラムが終了します。
  4. ユーザーはハンドラーまたはクリーンアップを知らないか気にせず、プログラムがnohupにもかかわらず終了したことを確認します。

これが「disown」の出番です。hashexitオプションに関係なく、BashによってdisownedされたプロセスにはHUPシグナルが送信されません。そのため、プログラムが独自のシグナルハンドラを設定しても、シグナルは実際には送信されないため、ハンドラは実行されません。ただし、プログラムがログアウトしているユーザーにテキストを表示しようとすると、I / Oエラーが発生し、プログラムが終了する可能性があることに注意してください。

*そして、はい、あなたが尋ねる前に、「ハングアップ」の用語はUNIXのダイアルアップメインフレーム時代から残っています。

**とにかく、ほとんどの信号。たとえば、SIGKILL は、プログラムを常にピリオドですぐに終了させます。


2

ポイントは1-4あなたの最後のポイントについては、細かなアプリケーション、ポイント約5 correct.I既知の何もない画面では、あなたはすべてのプロセスに関係なく、あなたの接続を終了する方法の、その自然の最後まで実行させることができます。画面はリポジトリにあります。

画面の男の説明は読みやすいものではありませんが、とりわけ、次のように述べています。

screenが呼び出されると、シェル(または指定されたコマンド)を含む単一のウィンドウが作成され、通常どおりプログラムを使用できるように邪魔になりません。その後、いつでも、他のプログラム(シェルを含む)を含む新しい(フルスクリーン)ウィンドウを作成したり、既存のウィンドウを削除したり、ウィンドウのリストを表示したり、出力ログのオンとオフを切り替えたり、テキストをコピーアンドペーストしたりできますウィンドウ間、スクロールバック履歴の表示、任意の方法でウィンドウ間を切り替えるなど。すべてのウィンドウは、プログラムを互いに完全に独立して実行します。 ウィンドウが現在表示されていない場合や、画面セッション全体がユーザーの端末から切り離されている場合でも、プログラムは引き続き実行されます。。プログラムが終了すると、screenは(デフォルトで)それを含むウィンドウを強制終了します。このウィンドウが前面にある場合、表示は前のウィンドウに切り替わります。何も残っていない場合、画面は終了します。

最も重要な部分を強調しました:Ctrl + a + dコマンドでウィンドウをデタッチできます。セッションを強制終了/ログアウトできます。デタッチされたウィンドウは、内部のプログラムが引き続き実行された状態で存続します。たとえば、新しいsshセッションを開始して接続し直すと、コマンドscreen -rは、以前に切り離されたscreenセッションを再開し、標準エラー/出力へのすべての出力がはっきりと表示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.