解決策 1:
2016 年の編集:
この Q&A は、systemd v230 の大失敗よりも前のものです。 systemd v230 の時点で、これを防ぐために歴史的に有効な予防措置がどのようなものであったかに関係なく、新しいデフォルトは、終了するログイン セッションのすべての子を強制終了することです。 KillUserProcesses=no
を設定することで動作を変更できます /etc/systemd/logind.conf
で 、またはユーザー空間でデーモンを起動するためのsystemd固有のメカニズムを使用して回避します。これらのメカニズムは、この質問の範囲外です。
以下のテキストは、Linux が存在するよりも長い間、UNIX デザインスペースで物事が伝統的にどのように機能してきたかを説明しています。
彼らは殺されますが、必ずしもすぐにではありません。 SSH デーモンが接続が切断されたと判断するまでにかかる時間によって異なります。以下は、それが実際にどのように機能するかを理解するのに役立つ、より長い説明です。
ログインすると、SSH デーモンが疑似端末を割り当て、それをユーザーの構成済みログイン シェルに接続します。これを制御端末と呼びます。その時点で通常どおりに起動するすべてのプログラムは、シェルの層の深さに関係なく、最終的にその祖先をそのシェルまでさかのぼります。これは pstree
で観察できます コマンド。
接続に関連付けられている SSH デーモン プロセスが、接続が切断されたと判断すると、ハングアップ シグナル (SIGHUP
) ログインシェルに。これは、シェルに、あなたが消えたことと、それ自体の後でクリーンアップを開始する必要があることを通知します.この時点で何が起こるかはシェル固有です (「HUP」のドキュメント ページを検索してください) が、ほとんどの場合、SIGHUP
の送信を開始します。 終了する前に、それに関連付けられた実行中のジョブに。これらの各プロセスは、そのシグナルを受信すると、構成されていることをすべて実行します。通常、それは終了を意味します。それらのジョブが独自のジョブを持っている場合、信号も同様に渡されることがよくあります。
制御端末のハングアップ後も存続するプロセスは、端末との関連付けを解除したプロセス (端末内で開始したデーモン プロセス) か、接頭辞 nohup
を付けて呼び出されたプロセスです。 指図。 (つまり、「これで電話を切らないでください」) デーモンは HUP シグナルを異なる方法で解釈します。制御端末がなく、HUP 信号を自動的に受信しないため、代わりに、構成を再ロードするための管理者からの手動要求として再利用されます。皮肉なことに、これはほとんどの管理者が、かなり後になるまで、非デーモンに対するこのシグナルの「ハングアップ」使用法を学習しないことを意味します。それがあなたがこれを読んでいる理由です!
端末マルチプレクサーは、切断間でシェル環境をそのまま維持する一般的な方法です。それらを使用すると、切断が偶発的であるか意図的であるかに関係なく、後で再接続できる方法でシェルプロセスから切り離すことができます。 tmux
と screen
より人気のあるものです。それらを使用するための構文は質問の範囲を超えていますが、調べる価値はあります。
SSH デーモンが接続が切断されたと判断するまでにかかる時間を詳しく説明するように求められました。これは、SSH デーモンのすべての実装に固有の動作ですが、いずれかの側が TCP 接続をリセットすると、それらすべてが終了することを期待できます。これは、サーバーがソケットへの書き込みを試みても TCP パケットが確認されない場合は迅速に発生し、PTY への書き込みが試みられていない場合はゆっくりと発生します。
この特定のコンテキストでは、書き込みをトリガーする可能性が最も高い要因は次のとおりです。
- サーバー側の PTY に書き込もうとしているプロセス (通常はフォアグラウンドにあるプロセス)。 (サーバー->クライアント)
- クライアント側で PTY に書き込もうとしているユーザー。 (クライアント->サーバー)
- あらゆる種類のキープアライブ。これらは通常、クライアントでもサーバーでもデフォルトでは有効になっておらず、通常、アプリケーション レベルと TCP ベースの 2 種類があります (例:
SO_KEEPALIVE
)。キープアライブは、ソケットに書き込む理由が他に何もない場合でも、サーバーまたはクライアントのいずれかが反対側にパケットをまれに送信することになります。これは通常、接続のタイムアウトが早すぎるファイアウォールを回避することを目的としていますが、相手側の応答がそれほど速くないときに送信者が気付くという追加の副作用があります。
ここでは、TCP セッションの通常のルールが適用されます。クライアントとサーバー間の接続が中断されたが、どちらの側も問題中にパケットを送信しようとしなかった場合、両方の側がその後応答し、予期された TCP を受信していれば、接続は存続します。
一方がソケットが死んでいると判断した場合、その影響は通常すぐに現れます:sshd プロセスは HUP
を送信します。 自己終了するか (前述のとおり)、クライアントは検出された問題をユーザーに通知します。一方が他方が死亡したと考えているからといって、他方がこれを通知されているわけではないことに注意してください。接続の孤立した側は、通常、書き込みを試みてタイムアウトになるか、反対側から TCP リセットを受信するまで開いたままになります。 (その時点で接続が利用可能だった場合)この回答で説明されているクリーンアップは、サーバー
解決策 2:
他の人が述べたように、ssh から切断すると、その中で実行されているものはすべてなくなります。
@Michael Hampton などが言及しているように、 tmux
のようなツールを使用できます または screen
端末のコンテンツ (つまり、子プロセス) を失うことなく、端末を切断/再接続します。
さらに、アンパサンド &
を使用してプロセスをバックグラウンドに入れることができます 次に、コマンド disown
を使用します それらを現在のシェルとの関連付けを解除します。
# start a command
% sleep 5000 &
[1] 3820
# check it
% jobs
[1]+ Running sleep 5000 &
# disown everything
% disown -a
# check it again (gone from shell)
% jobs
%
# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml 3820 23791 0 00:16 pts/1 00:00:00 sleep 5000
%
解決策 3:
いいえ、まだ端末に接続されていて、nohup
のようなものでバックグラウンドに配置されていないプログラムはありません 、殺されます。
これが、tmux
のような仮想端末ソリューションがある理由です。 そして古い screen
切断されても実行を継続し、後で再接続できるセッションを作成します。