Wie mache ich ssh mit einer Zeitüberschreitung in einem Skript?

172

Ich führe ein Skript aus, das über SSH ohne Kennwort auf einem Remote-Host eine Verbindung herstellt. Ich möchte ein Zeitlimit festlegen, damit ich, wenn die Ausführung des Remote-Hosts unendlich lange dauert, aus dieser SSH-Sitzung herauskomme und andere Zeilen in meinem SH-Skript fortsetze.

Irgendeine Idee, wie es geht?

user57421
quelle
Dies sollte wahrscheinlich geschlossen werden, um mit dem Schließen eines vollständigen Duplikats davon übereinzustimmen, wie der Zeitlimitwert für die SSH-Verbindung verringert werden kann [geschlossen]
Murmel
Wenn Sie hier nur umgeleitet haben, um "mehr Zeit in Ihrer sshSitzung zu bleiben " (Frage "Wie kann das Zeitlimit für SSH-Verbindungen erhöht werden?"), Ist dies der falsche Ort . Die Antwort ist unter diesem Link über ssh-timeout .
Peter Krauss

Antworten:

287
ssh -o ConnectTimeout=10  <hostName>

Wobei 10 Zeit in Sekunden ist. Dieses Zeitlimit gilt nur für die Erstellung der Verbindung.

user57421
quelle
4
ConnectTimeout legt nur eine Zeitüberschreitung beim Verbindungsaufbau fest, oder?
Aurélien Ooms
10
Dies funktioniert nicht wirklich für "Der Remote-Host benötigt unendlich
viel
108

Verwenden Sie das -o ConnectTimeoutund -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout verhindert, dass das Skript hängt, BatchMode verhindert , dass es mit unbekanntem Host hängt, JA, um es zu bekannten_Hosts hinzuzufügen, und StrictHostKeyChecking fügt den Fingerabdruck automatisch hinzu.

**** HINWEIS **** Das "StrictHostKeyChecking" war nur für interne Netzwerke gedacht, in denen Sie Ihren Hosts vertrauen. Abhängig von der Version des SSH-Clients kann der Client unter "Sind Sie sicher, dass Sie Ihren Fingerabdruck hinzufügen möchten" auf unbestimmte Zeit hängen bleiben (hauptsächlich alte Versionen, die unter AIX ausgeführt werden). Die meisten modernen Versionen leiden nicht unter diesem Problem. Wenn Sie mit Fingerabdrücken mit mehreren Hosts arbeiten müssen, empfehle ich, die Datei unknown_hosts mit einem Konfigurationsmanagement-Tool wie Puppet / Ansible / Chef / Salt / etc. Zu verwalten.

Doug
quelle
11
-o StrictHostKeyChecking=noDie Frage wird nicht nur nicht beantwortet, es ist auch eine schreckliche Idee, wenn Sie sich um Sicherheit kümmern. Dies könnte der Grund sein, warum Sie SSH überhaupt verwenden.
Dolph
9
Es ist gut, auf die möglichen Auswirkungen von -o StrictHostKeyChecking = no auf die Sicherheit hinzuweisen. Es wird jedoch verhindert, dass das Skript während der Ausführung hängen bleibt.
Doug
2
WARNUNG!!!! Wie @Dolph schrieb, verwenden Sie es NICHT, StrictHostKeyChecking=nowenn Sie sich überhaupt um Sicherheit kümmern. @Doug: Das Skript hängt nicht - es besteht nur darauf, dass Sie beim ersten Mal manuell zum Remote-Host ssh, damit es den Host kennenlernt. Aber es schützt Sie vor MITM-Angriffen. Bitte bearbeiten Sie diese Antwort, um dies widerzuspiegeln, da es sich derzeit um einen sehr gefährlichen Rat handelt. Und es wurde nicht einmal danach gefragt.
Johndodo
2
Meine Antwort wurde aktualisiert. Nach meiner Erfahrung kann dies dazu führen, dass einige Kunden hängen bleiben.
Doug
50

Versuche dies:

timeout 5 ssh user@ip

timeout führt den Befehl ssh (mit Argumenten) aus und sendet ein SIGTERM, wenn ssh nach 5 Sekunden nicht zurückkehrt. Weitere Informationen zum Timeout finden Sie in diesem Dokument: http://man7.org/linux/man-pages/man1/timeout.1.html

oder Sie können den Parameter von ssh verwenden:

ssh -o ConnectTimeout=3 user@ip
Lee HoYo
quelle
4
Wenn Sie diesen Befehl auf einem Mac suchen, versuchen Sie es brew install coreutilsund verwenden Sie ihn gtimeout (Quelle: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
Lärche
3
Dies kann nicht tun, was Sie wollen. Betrachten Sie den Befehl timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Dies beendet den Prozess auf der SSH-Clientseite, aber / tmp / blarg wird auf dem Remote-Server immer noch geändert. Dies bedeutet, dass Sie Prozesse verlieren, wenn Sie einen außer Kontrolle geratenen CPU-intensiven Job auf dem Remote-Server ausführen.
Jamie Davis
1
@JamieDavis was ist mit ssh user @ server 'timeout 5s sleep 10'?
FilipR
18

Sie können sich auch mit flag verbinden

-o ServerAliveInterval = <Sekunden>
Daher sendet der SSH-Client jede <secs>Sekunde ein Nullpaket an den Server , um die Verbindung aufrechtzuerhalten. Unter Linux kann dies auch global in /etc/ssh/ssh_configoder pro Benutzer in festgelegt werden ~/.ssh/config.

Patrizio Bertoni
quelle
4
Das klingt wie das Gegenteil von dem, was die Frage verlangt.
Davor Cubranic
1

Wenn alles andere fehlschlägt (einschließlich des Fehlens des timeoutBefehls), funktioniert das Konzept in diesem Shell-Skript:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi
Philip Kearns
quelle
0

Nun, Sie könnten nohup verwenden, um alles auszuführen, was Sie im "nicht blockierenden Modus" ausführen. Sie können also einfach weiter prüfen, ob alles, was ausgeführt werden soll, ausgeführt oder ansonsten beendet wurde.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Skript beendet am 15. Februar 2011, 9:20 Uhr"> /tmp/done.txt

Im zweiten Fall überprüfen Sie einfach, ob die Datei vorhanden ist.

Eduardo
quelle
Macht Sinn. Aber das Skript, das ausgeführt wird, gibt mir eine Ausgabe, die auf der Konsole angezeigt wird. Wie kann ich überprüfen, ob mein vorheriges Skript ausgeführt oder beendet wurde? $? oder sonst noch was?
user57421
Nun, Sie könnten dieses Skript dazu bringen, eine Datei zu erstellen, wenn Sie fertig sind. Ich habe den Kommentar zur Antwort hinzugefügt .... grrr
Eduardo