Sind Programme, die von einer SSH-Sitzung ausgeführt werden, von der Verbindung abhängig?

29

Hängt ein Programm, das von einer SSH-Sitzung ausgeführt wird, von der Verbindung zum Client ab? Zum Beispiel, wenn die Verbindung sehr langsam ist. Wartet es also aktiv, bis Dinge auf dem Bildschirm gedruckt werden?

Und wenn es auf die Verbindung ankommt , kommt es zum Beispiel auch bei screen oder byobu vor ? Denn bei diesen laufen die Programme auch nach dem Trennen vom Host weiter.


Hinweis: Ich habe nur diese verwandten Fragen gefunden:

ein Gold
quelle
1
Beachten Sie, dass bei einem Verbindungsverlust das Programm so lange ausgeführt wird, bis das Sitzungszeitlimit abgelaufen ist (es sei denn, es steckt in einem Druckvorgang). Wenn Ihre Sitzung jedoch beendet wird, wird das Programm ordnungsgemäß beendet.
Sebb

Antworten:

26

Die Ausgabe von Programmen wird gepuffert. Wenn die Verbindung langsam ist, wird das Programm angehalten, wenn der Puffer voll ist.

Wenn Sie verwenden screen, verfügt es auch über einen Puffer, mit dem versucht wird, eine verbundene Sitzung anzuzeigen. Ein in der Bildschirmsitzung verbundenes Programm wird jedoch nicht gestoppt, wenn screendas Remote-Terminal nicht schnell genug aktualisiert werden kann. Genau wie bei einem Verbindungsverlust füllt das Programm den screensPuffer weiter, bis er überläuft (wobei die ältesten Informationen ausgelesen werden). Was Sie sehen (und zurückblättern können), hängt davon ab, was sich (noch) in diesem Puffer befindet. screenTrennt Ihr Programm effektiv von Ihrem Terminal (und Ihrer langsamen SSH-Verbindung).

Anthon
quelle
9

Eine SSH-Verbindung kann vorzeitig abstürzen, wenn die zugrunde liegende TCP-Verbindung ein Paket mit dem RST- Flag empfängt . Dies kann der Fall sein, wenn eine Seite ein Paket sendet (bei dem es sich möglicherweise um einen regelmäßigen SSH-Keepalive-Test handelt), aber in angemessener Zeit keine TCP-Bestätigung erhält oder wenn ein Router feststellt, dass die Verbindung zu lange inaktiv war, oder wenn ein ISP ist nur böse.

Wenn im Unix-Terminalmodell die Terminalverbindung getrennt wird, sendet der Terminaltreiber ein HUP-Signal an die Shell, dessen Beendigung auch bewirkt, dass ein SIGHUP an Prozesse gesendet wird, die in der Shell ausgeführt werden.

In den Unix Programmer FAQ , Punkt 1.15:

SIGHUPist ein Signal, das laut Konvention bedeutet, dass "die Terminalleitung aufgelegt wurde". Es hat nichts mit übergeordneten Prozessen zu tun und wird normalerweise vom tty-Treiber generiert (und an die Vordergrundprozessgruppe übergeben).

Als Teil des Sitzungsverwaltungssystems gibt es jedoch genau zwei Fälle, in denen SIGHUPder Tod eines Prozesses gemeldet wird:

  • Wenn der Prozess, der stirbt, der Sitzungsleiter einer Sitzung ist, die an ein Endgerät angeschlossen ist, SIGHUPwird er an alle Prozesse in der Vordergrundprozessgruppe dieses Endgeräts gesendet.

  • Wenn der Tod eines Prozesses einer Prozessgruppe veranlasst werden verwaiste, und einen oder mehrere Prozesse in der Gruppe verwaiste werden gestoppt , dann SIGHUPund SIGCONTwerden an alle Mitglieder der Gruppe verwaiste gesendet. (Eine verwaiste Prozessgruppe ist eine Prozessgruppe, bei der kein Prozess in der Gruppe ein übergeordnetes Element hat, das Teil derselben Sitzung, jedoch nicht derselben Prozessgruppe ist.)

Der Standard-Signal-Handler für SIGHUP ist das Beenden des Prozesses:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Es ist jedoch möglich, eine Beendigung des Prozesses zu vermeiden.

  • Sie können einen Signalhandler einfügen, der SIGHUP ignoriert. Um dies als Benutzer zu tun, wickeln Sie den Befehl in nohup. Beispielsweise:

    nohup make all &
    
  • Sie können die Shell anweisen, einen untergeordneten Prozess von ihm zu trennen. Zum Beispiel hat Bash einen disowneingebauten Befehl:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Dann wird der SIGHUP nicht an das Kind weitergegeben (das kein Kind mehr ist).

  • Einige Programme, insbesondere Daemons , verwenden die oben genannten Mechanismen automatisch: Ein Programm kann einen alternativen SIGHUP-Handler installieren (mithilfe von sigaction(2)) oder sich für eine neue Sitzung entscheiden ( setsid(2)).
  • Sie können screenoder ausführen tmux, das ein Pseudo-TTY zuweist, um eine Sitzung mit einer Shell auszuführen, die das SIGHUP nicht empfängt, wenn die SSH-Verbindung unterbrochen wird. Das SIGHUP wird nicht von der SSH-Sitzung an die screen / tmux-Sitzung weitergeleitet.

Im Übrigen besteht eine alternative Möglichkeit, mit unzuverlässigen SSH-Verbindungen umzugehen , darin, stattdessen das Mosh- Protokoll zu verwenden. Mosh läuft über UDP, es gibt also keine TCP-Verbindung, die möglicherweise zurückgesetzt wird.

200_erfolg
quelle
Lesen Sie weiter: Unterschied zwischen nohup, disown und & .
200_erfolg
1

Ja, ein Programm, das über SSH läuft, hängt davon ab, ob die Ausgabe irgendwo abläuft. Wenn die Verbindung langsam ist, muss die Ausgabe irgendwo gepuffert werden und die Puffer können nicht unendlich sein, daher muss das Programm blockieren, wenn sie gefüllt sind.

Beachten Sie, dass die Ausgabe möglicherweise nicht unbedingt an ein Terminal gesendet wird

ssh user@somewhere "cat file.txt" > file.txt

Dadurch wird die Datei tatsächlich kopiert. Damit dies funktioniert, muss die Ausgaberate von cat mit der der Verbindung übereinstimmen: Es sollte offensichtlich sein, dass ein Verlust von Teilen der Ausgabe aus der Mitte inakzeptabel wäre.

Der Bildschirm ändert die Situation dahingehend, dass er sich wie ein Terminal verhält und speichert, was "im Terminalfenster" angezeigt werden soll (plus Scrollback). Es muss sich nicht alles merken, was Ihr Programm ausgibt, sondern nur die Teile, die in das "Fenster" und den Bildlauf passen. Standardmäßig wartet der Bildschirm auf eine langsame Verbindung (Blockierung des Programms), aber er kann so konfiguriert werden, dass eine blockierte Verbindung erkannt wird, indem "nonblock on" eingestellt wird.

Von der Manpage:

nonblock [on | off | numsecs]

Sagen Sie dem Bildschirm, wie mit Benutzeroberflächen (Displays) umgegangen werden soll, die die Ausgabe nicht mehr akzeptieren. Dies kann passieren, wenn ein Benutzer ^ S drückt oder eine TCP / Modem-Verbindung getrennt wird, aber kein Auflegen empfangen wird. Wenn nonblock deaktiviert ist (dies ist die Standardeinstellung), wartet der Bildschirm, bis die Anzeige neu gestartet wird, um die Ausgabe zu akzeptieren. Wenn nonblock aktiviert ist, wartet der Bildschirm, bis das Timeout erreicht ist (on wird als 1s behandelt). Wenn das Display immer noch keine Zeichen empfängt, wird es vom Bildschirm als "blockiert" betrachtet und das Senden von Zeichen wird gestoppt. Wenn es zu einem bestimmten Zeitpunkt erneut gestartet wird, um Zeichen zu akzeptieren, wird die Anzeige auf dem Bildschirm freigegeben und der aktualisierte Fensterinhalt wird erneut angezeigt.

Eine Trennung unterscheidet sich von einer langsamen Verbindung. Normales SSH kann nicht automatisch wiederhergestellt werden, sodass Ihr Programm einen SIGHUP erhält. Auf der anderen Seite erkennt der Bildschirm eine Unterbrechung, löst sich und greift auf die lokale Pufferung zurück, bis der Bildschirm wieder angeschlossen wird. Das laufende Programm wird dadurch nicht blockiert.

(Das Einstellen nonblock 1von "your" .screenrcist wichtig, wenn Sie so etwas wie "irssi" ausführen, das kontinuierlich Ausgabe erzeugt, aber dennoch gleichzeitig mit dem Netzwerk kommunizieren muss. Das Blockieren würde dazu führen, dass die Verbindung zum IRC getrennt wird, was äußerst ärgerlich ist ...)

ilkkachu
quelle