Schließen der Verbindung nach dem Neustart mit dem Befehl ssh

18

Ich verwende den reboot -fBefehl remote, um einen Neustart eines Unix-Rechners zu erzwingen. Das Problem ist, dass die SSH-Verbindung für eine lange Zeit aktiv bleibt, ich weiß nicht warum? Ich möchte die SSH-Verbindung sofort nach dem Neustart des Computers schließen und zu meiner lokalen Shell zurückkehren. Wie kann ich das machen? Beachten Sie, dass der Neustartbefehl ohne -fFlag nicht funktioniert.

Kaffeebecher
quelle
1
Warum beenden Sie nicht einfach Ihre Remoteverbindung (Strg + D) und lassen den Server neu starten, ohne dass Sie die Shell-Eingabeaufforderung beobachten müssen?
gertvdijk
Wie kann ich das im selben Befehl tun?
coffeMug
2
Ich habe eine Lösung dafür gefunden, die auch für andere hilfreich sein könnte. Ich habe den folgenden Befehl verwendet, um die Verbindung direkt nach dem Start des an ssh angehängten Befehls zu schließen: ssh host "Befehl zur Ausführung auf dem Hostcomputer> / dev / null &" Ich verstehe nicht vollständig, warum dieser Befehl die Verbindung zu erzwingt fast fertig, aber zumindest war es hilfreich für mich. Wenn jemand versteht, wie die Ausgabe des Befehls an / dev / null geleitet wird und warum dadurch die ssh-Verbindung unterbrochen wird, wäre es nett, wenn er / sie dies erklären könnte. :-)
coffeMug
Befehl "ssh host" zum Ausführen auf dem Hostrechner> / dev / null & "
coffeMug
1
Es ist keine Antwort auf diese Frage, aber es ist trotzdem nützlich zu wissen: Der SSH-Client verfügt über eine Reihe von Steuerzeichen, mit denen unter anderem der Client getötet werden kann. Steuerzeichen werden erst unmittelbar nach einer neuen Zeile erkannt. Beginnen Sie also mit Enter. Dann zB ~.um die Sitzung zu beenden. Enter ~?für eine Liste von anderen.
Tom

Antworten:

22

Der Befehl wird reboot -fnie zurückgegeben (es sei denn, Sie hatten keine Berechtigung, einen Neustart durchzuführen). Zum Zeitpunkt der Ausgabe wartet der SSH-Client auf Folgendes:

  • Der SSH-Server benachrichtigt den Client darüber, dass etwas passiert ist, das seine Aufmerksamkeit erfordert, z. B. dass eine Ausgabe angezeigt werden muss oder dass der Remote-Befehl beendet wurde.
  • ein Ereignis auf der Client-Seite, z. B. ein Signal zum Weiterleiten;
  • Es wird ein Timer ausgelöst, der den Client veranlasst, eine Keepalive-Nachricht zu senden (und die Verbindung zu schließen, wenn der Server nicht antwortet).

Da der SSH-Serverprozess tot ist, stirbt der SSH-Client erst, wenn der Zeitgeber ausgelöst wird.

Wenn Sie rennen ssh remotehost 'reboot -f >/dev/null &', passiert Folgendes:

  1. Die Remote-Shell startet den rebootBefehl im Hintergrund.
  2. Da der serverseitige Shell-Befehl beendet wurde und kein Prozess den Dateideskriptor für die Standardausgabe offen hält, schließt der SSH-Server die Verbindung.
  3. Der rebootBefehl bewirkt einen Neustart des Computers.

Dies ist jedoch nicht zuverlässig: Abhängig vom Timing kann Schritt 3 vor Schritt 2 erfolgen. Das Hinzufügen eines Timers macht Folgendes unwahrscheinlich:

ssh remotehost '{ sleep 1; reboot -f; } >/dev/null &'

Um absolut sicherzugehen, dass die Serverseite für die Ausführung festgeschrieben ist, rebootund gleichzeitig sicherzustellen, dass sie nicht neu gestartet wird, bevor der Client über die Festschreibung benachrichtigt wird, benötigen Sie eine zusätzliche Benachrichtigung, um vom Server zum Client zu wechseln. Dies kann über die SSH-Verbindung ausgegeben werden, wird jedoch kompliziert.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Für den Fall , sucht jemand einen Weg , dies zu tun , aus der Remote - Host (ähnliche Lösung): (sleep 1 && sudo reboot &) && exit. Die Klammern erzeugen einen Unterprozess, der eine Sekunde wartet und dann den Neustart einleitet. Der Host-Prozess beendet die ssh-Sitzung jedoch sofort. Ich bin kein Shell-Guru, aber das hat bisher bei mir funktioniert.
Griddo
@Griddo Das hat fantastisch funktioniert und ist ein ordentlicher kleiner Hack. Ich liebe es. Danke für das Teilen!
Joshua Pinter
5

Ich fand diese Lösung am besten für mich.

Verwenden Sie -o "ServerAliveInterval 2"mit Ihrem sshBefehl wie folgt:

$ ssh -o "ServerAliveInterval 2" root@remotehost reboot

Diese Option veranlasst die Clientseite, den Server alle 2 Sekunden über einen sicheren Kanal anzusteuern. Wenn der Neustart fortgesetzt wird, reagiert er nicht mehr und der Client trennt die Verbindung.

Roman Saveljev
quelle
Danke Roman, funktioniert wie Zauberei! :)
stdcerr
3

Einige Antworten waren knapp, aber die richtige Antwort lautet:

ssh [email protected] "nohup sudo reboot &>/dev/null & exit"

Erläuterung:

  • Sie möchten exitals letzten Befehl den Status 0 (Erfolg) des letzten Befehls angeben. Wenn Sie möchten, können Sie einen Schlaf vorbereiten, dies ist jedoch nicht erforderlich
  • Sie müssen einen Neustart im Hintergrund ausführen, da sonst der Server die Verbindung schließt und Sie eine Fehlermeldung erhalten. Es wird auf den meisten Systemen immer noch neu gestartet, aber wenn Sie ein Skript ausführen, ist der Rückgabestatus ein Fehler (nicht 0), auch wenn der Befehl ordnungsgemäß ausgeführt wird
  • im Hintergrund zu laufen reicht nicht aus, da die stdinund stdoutweiterhin über SSH mit dem virtuellen Terminal verbunden sind, so dass die Verbindung nicht geschlossen wird. Sie müssen zwei zusätzliche Schritte ausführen, damit die SSH-Sitzung beendet wird und der Befehl im Hintergrund ausgeführt wird.
    • 1) müssen Sie umleiten stdoutund stderrzu , /dev/nullso dass sie durch das virtuelle Terminal nicht weitergeleitet werden, der die SSH - Sitzung hält. Das ist der &>/dev/nullTeil.
    • 2) Sie müssen auf stdindie gleiche Weise zu einer nicht lesbaren Datei umleiten . Das macht die eingebaute Shell nohup.

Wenn nur ein Befehl im Hintergrund ausgeführt wird, der in keiner Weise vom Terminal getrennt wurde, exitwird die Sitzung geschlossen, und da auf dem virtuellen Terminal kein stdinoder kein stdoutSSH mehr vorhanden ist, wird die Verbindung ohne Fehler beendet.

Nachoparker
quelle
1

Ich benutze den folgenden Befehl:

ssh -t <hostname> 'sudo shutdown --reboot 0 && exit'

Folgendes tut dies:

  • Es weist den Computer an, im nächsten Moment neu zu starten, jedoch nicht während dieses Befehls
  • Verlässt SSH sauber
  • Behält das SSH TTY die ganze Zeit bei, damit sudo zufrieden ist und ordnungsgemäß ausgeführt werden kann.
stieg
quelle
0

Hast du folgendes versucht

# shutdown -r now

Ich stelle fest, dass auf einigen Systemen, an denen ich in der Zwischenzeit gearbeitet habe, der Befehl zum Neustart einige Probleme hatte. Andererseits kann ich in der Manpage von shutdown nichts finden, was dasselbe bewirken würde wie einen Neustart mit dem Flag -f.

Silverrocker
quelle
1
Ja, das Herunterfahren funktioniert nicht auf dem Computer, zu dem ich aus seltsamen Gründen eine Verbindung herstellen möchte. Aus diesem Grund verwende ich reboot -f, um das Herunterfahren und den Neustart zu erzwingen.
coffeMug
0

Wie wäre es, wenn Sie die SSH-Sitzung beenden und das System mit dem nächsten Befehl neu starten würden:

ssh login@host "reboot -f"

Drücken Sie danach einfach Strg + C, um ssh zu beenden.

Renat Zaripov
quelle
0

Ich habe eine Lösung dafür gefunden, die auch für andere hilfreich sein könnte. Ich habe den folgenden Befehl verwendet, um die Verbindung direkt nach dem Start des an ssh angehängten Befehls zu schließen:

ssh host "command to run on the host machine > /dev/null &"

Ich verstehe nicht genau, warum dieser Befehl das Schließen der Verbindung erzwingt, aber es war zumindest hilfreich für mich. Wenn jemand versteht, warum es die SSH-Verbindung beendet; bitte erkläre.

Kaffeebecher
quelle
0

Dies erfordert eine Verzögerung von 1 Minute, hat aber bei mir zuverlässig funktioniert und löst das Problem, dass der SSH-Client hängen bleibt:

    $ sudo shutdown +1; logout

Dadurch wird das Herunterfahren des Systems für eine Minute später geplant, wodurch Zeit für das Abmelden und damit für die Beendigung von SSH verbleibt. Wenn Sie so wenig Zeit wie möglich warten möchten, können Sie die ersetzen +1mit HH:MMeiner rasch näher Tageszeit , aber das kann richtig Zeit schwierig sein und zu einer 59 Sekunden Verzögerung kann bis.

trpropst
quelle
0

Eine einfache Möglichkeit, die ich gefunden habe, besteht darin, das Herunterfahren / Neustarten als Hintergrundaufgabe zu befehlen (mit '&') und es vor dem Schließen zu schützen, wenn die Sitzung mit 'nohup' geschlossen wird, zusammen mit dem sofortigen Beenden der Shell / Sitzung:

nohup shutdown -r now & exit

Auf diese Weise bleibt der SSH-Client nicht hängen, da die Sitzung sofort beendet wird, während das ferne System asynchron neu gestartet wird.

MikeW
quelle
Oder ersetzen Sie das Äquivalent Ihres Systems durch "shutdown -r now" für einen Neustart ....
MikeW
-2

Versuchen Sie diesen Befehl:

$ reboot -f && exit
tH0r
quelle
2
Das funktioniert leider nicht.
coffeMug
1
@AKh_Sw Seien Sie spezifisch für "funktioniert nicht".
gertvdijk
@AKh_Sw: Wenn Sie das '$' - Zeichen eingegeben haben, funktioniert es nicht
TH0R
1
Nutzlos. Das ist genau gleichbedeutend mit reboot -f.
Gilles 'SO - hör auf böse zu sein'