Bricht es Ihre Programme, wenn Sie von einer SSH-Sitzung getrennt werden?

88

Also, sage ich von einer SSH-Sitzung der Verbindung unterbrochen wird, nachdem ich habe angefangen , rsyncoder cpoder anderen Befehl, die lange Lauf sein kann. Wird dieser Befehl so lange ausgeführt, bis er beendet ist, nachdem ich die Verbindung getrennt habe, oder wird er einfach getötet?

Ich habe mich immer gefragt.

Fregas
quelle
Ich möchte nur hinzufügen, was oben gesagt wurde: Wenn Sie sich in einer Situation befinden, in der Sie einen bereits laufenden Prozess ausführen müssenscreen , versuchen Sie es mit reptyr .
Ein trauriger Typ
Es wird Ihre Programme töten. Sehr ärgerlich, wenn Sie die Betriebssystemversion von Ubuntu 16.04 auf 17.10 über SSH
aktualisieren

Antworten:

118

Bearbeiten für 2016:

Diese Fragen und Antworten sind älter als das systemd v230-Debakel . Ab systemd v230 werden standardmäßig alle Kinder einer abbrechenden Anmeldesitzung getötet, unabhängig davon, welche historisch gültigen Vorsichtsmaßnahmen getroffen wurden, um dies zu verhindern. Das Verhalten kann durch Einstellung geändert wird KillUserProcesses=noin /etc/systemd/logind.conf, oder zum Starten eines Dämons in Userspace mit den systemd spezifischen Mechanismen umgangen. Diese Mechanismen sind nicht Gegenstand dieser Frage.

Der folgende Text beschreibt, wie Dinge im UNIX-Designspace traditionell länger funktionierten, als es Linux gab.


Sie werden getötet, aber nicht unbedingt sofort. Es hängt davon ab, wie lange es dauert, bis der SSH-Dämon feststellt, dass Ihre Verbindung unterbrochen ist. Was folgt, ist eine längere Erklärung, die Ihnen helfen wird, zu verstehen, wie es tatsächlich funktioniert.

Bei der Anmeldung hat der SSH-Dämon ein Pseudoterminal für Sie zugewiesen und dieses an die konfigurierte Anmeldeshell Ihres Benutzers angehängt. Dies wird als steuerndes Terminal bezeichnet. Jedes Programm, das Sie normalerweise an diesem Punkt starten, egal wie viele Schichten von Shells tief sind, wird letztendlich seine Herkunft auf diese Shell zurückführen. Sie können dies mit dem pstreeBefehl beobachten.

Wenn der Ihrer Verbindung zugeordnete SSH-Daemon-Prozess feststellt, dass Ihre Verbindung nicht mehr funktioniert, sendet er ein Aufhängesignal ( SIGHUP) an die Anmeldeshell. Dies benachrichtigt die Shell, dass Sie verschwunden sind und dass sie nach sich selbst mit dem Aufräumen beginnen soll. Was zu diesem Zeitpunkt passiert, ist Shell-spezifisch (suchen Sie auf der Dokumentationsseite nach "HUP"), aber zum größten Teil werden SIGHUPdie damit verbundenen Jobs vor dem Beenden gesendet. Jeder dieser Prozesse wird nach Empfang dieses Signals das tun, wofür er konfiguriert ist. Normalerweise bedeutet das, dass Sie kündigen müssen. Wenn diese Jobs eigene Jobs haben, wird das Signal oft auch weitergeleitet.

Die Prozesse, die ein Auflegen des steuernden Terminals überleben, haben sich entweder von einem Terminal getrennt (Dämonprozesse, die Sie in diesem gestartet haben) oder wurden mit einem vorangestellten nohupBefehl aufgerufen . Daemons interpretieren das HUP-Signal unterschiedlich. Da sie kein steuerndes Terminal haben und kein automatisches HUP-Signal empfangen, wird es stattdessen als manuelle Aufforderung des Administrators zum erneuten Laden der Konfiguration verwendet. Ironischerweise bedeutet dies, dass die meisten Administratoren erst viel später lernen, wie dieses Signal für Nicht-Daemons "aufgehängt" wird. Deshalb liest du das hier!

Terminal-Multiplexer sind eine übliche Methode, um die Shell-Umgebung zwischen den Unterbrechungen intakt zu halten. Mit ihnen können Sie die Verbindung zu Ihren Shell-Prozessen auf eine Weise trennen, die Sie später erneut herstellen können, unabhängig davon, ob diese Trennung versehentlich oder absichtlich erfolgte. tmuxund screensind die populäreren; Die Syntax für ihre Verwendung würde den Rahmen Ihrer Frage sprengen, aber es lohnt sich, sie zu untersuchen.


Es wurde angefordert, dass ich näher erläutere, wie lange es dauert, bis der SSH-Dämon feststellt, dass Ihre Verbindung unterbrochen ist. Dies ist ein Verhalten, das für jede Implementierung eines SSH-Dämons spezifisch ist. Sie können sich jedoch darauf verlassen, dass alle von ihnen beendet werden, wenn eine der beiden Seiten die TCP-Verbindung zurücksetzt. Dies geschieht schnell, wenn der Server versucht, auf den Socket zu schreiben, und die TCP-Pakete nicht bestätigt werden, oder langsam, wenn nichts versucht, auf den PTY zu schreiben.

In diesem speziellen Kontext sind die Faktoren, die am wahrscheinlichsten einen Schreibvorgang auslösen, folgende:

  • Ein Prozess (normalerweise der im Vordergrund), der versucht, auf der Serverseite auf den PTY zu schreiben. (Server-> Client)
  • Der Benutzer, der versucht, auf der Clientseite auf das PTY zu schreiben. (Client-> Server)
  • Keepalives jeglicher Art. Diese sind normalerweise nicht standardmäßig aktiviert, weder vom Client noch vom Server. In der Regel gibt es zwei Varianten: Anwendungsebene und TCP-basiert (dh SO_KEEPALIVE). Keepalives bedeuten, dass entweder der Server oder der Client selten Pakete an die andere Seite senden, auch wenn sonst nichts einen Grund zum Schreiben in den Socket hätte. Dies ist in der Regel dazu gedacht, Firewalls zu umgehen, bei denen die Verbindung zu schnell unterbrochen wird, hat jedoch den zusätzlichen Nebeneffekt, dass der Absender bemerkt, dass die andere Seite nicht so schnell reagiert.

Hierbei gelten die üblichen Regeln für TCP-Sitzungen: Wenn die Verbindung zwischen Client und Server unterbrochen wird, jedoch keine Seite versucht, während des Problems ein Paket zu senden, bleibt die Verbindung bestehen, sofern beide Seiten anschließend reagieren und das erwartete TCP empfangen Sequenznummern.

Wenn eine Seite entschieden hat, dass der Socket tot ist, sind die Auswirkungen in der Regel sofort: Der sshd-Prozess wird gesendet HUPund automatisch beendet (wie oben beschrieben), oder der Client benachrichtigt den Benutzer über das erkannte Problem. Es ist erwähnenswert, dass nur, wenn eine Seite denkt, dass die andere tot ist, dies nicht bedeutet, dass die andere Seite darüber informiert wurde. Die verwaiste Seite der Verbindung bleibt in der Regel geöffnet, bis entweder versucht wird, darauf zu schreiben, und eine Zeitüberschreitung auftritt, oder ein TCP-Reset von der anderen Seite empfangen wird. (Wenn zu diesem Zeitpunkt eine Verbindung verfügbar war) Die in dieser Antwort beschriebene Bereinigung wird nur durchgeführt, wenn der Server dies bemerkt hat.

Andrew B
quelle
3
Ich würde dieser Liste auch den Befehl 'dtach' hinzufügen - das ist insofern das Gegenteil von screen / tmux, als Sie damit mehrere Terminals an eine einzige Sitzung anschließen können und eine Sitzung verlängern können, obwohl dies nicht der Fall ist Bieten Sie die Möglichkeit, die jüngste Historie abzuspielen.
Flauschige
dtachDie URL ist hier: dtach.sourceforge.net
slm
2
ausgezeichnete Erklärung. Ich fühle mich schon mehr linuxey!
Fregas
3
Auch wenn dies technisch gesehen nicht zu Ihrer Antwort gehört, gibt es hier ein interessantes Trivia: Sie können kill -HUPals root verwenden, um das Terminal eines anderen zum Auflegen zu zwingen. Sie sollten dies nicht ohne guten Grund tun. Ich schaffe den größten Teil meiner Laufleistung, wenn Benutzer während der Wartung Shells laufen lassen und ich ein Dateisystem aushängen muss, dessen Shell geöffnet bleibt. Wenn der Benutzer verbunden ist, sich jedoch im Leerlauf befindet, senden Sie das Signal an den sshd-Prozess. Wenn es in einem Terminal-Multiplexer ausgeführt wird, senden Sie es andernfalls an die Shell, die gestoppt werden soll. Hänge nur die Muschel auf, damit du nicht arbeitest!
Andrew B
@AndrewB, könnten Sie bitte erläutern, wie "der SSH-Daemon-Prozess ... entscheidet, dass Ihre Verbindung unterbrochen ist"? Und woher kann ich wissen, ob der SSH-Dämon denkt / weiß, dass die (welche) Verbindung unterbrochen ist oder nicht?
Xiao Peng - ZenUML.com
22

Wie bereits erwähnt, ist alles, was darin läuft, verschwunden, sobald Sie die Verbindung zu ssh trennen.

Wie @Michael Hampton und andere bereits erwähnt haben, können Sie Tools wie tmuxoder verwenden screen, um die Verbindung zu Terminals zu trennen / wiederherzustellen, ohne deren Inhalt zu verlieren (dh untergeordnete Prozesse).

Außerdem können Sie einen Prozess mit einem kaufmännischen Und in den Hintergrund stellen &und dann mit dem Befehl disowndie Zuordnung zur aktuellen Shell aufheben.

# 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
%
slm
quelle
Ist es möglich, eine Terminalsitzung wieder mit einem disownBearbeitungsprozess zu verbinden?
Fake Name
4
Ja. Weitere Informationen finden Sie in dieser U & L-Frage: unix.stackexchange.com/questions/4034/…
slm
13

Nein, alle Programme, die noch mit dem Terminal verbunden sind und nicht in den Hintergrund gestellt werden nohup, werden abgebrochen.

Aus diesem Grund gibt es virtuelle Terminallösungen wie tmuxund ältere, screendie Sitzungen erstellen, die auch dann weiterlaufen, wenn Sie nicht verbunden sind, und zu denen Sie später eine erneute Verbindung herstellen können.

Michael Hampton
quelle