Linux-Befehl zum Warten auf den Betrieb eines SSH-Servers


8

Ich habe ein Skript, das eine virtuelle Maschine erstellt und mir eine IP-Adresse zurückgibt. Dann möchte ich so etwas machen:

waitforssh 192.168.2.38 && ssh 192.168.2.38

Und es wird warten, bis die Maschine hochgefahren ist und ssh reagiert, dann ssh hinein.

waitforssh ist der Befehl, den ich finden muss.

Würden nmap, netcat, fping oder ping den Job machen? Ich habe Netcat ausprobiert, aber es gibt in nur wenigen Sekunden auf, wenn der Host nicht erreichbar ist.

Es muss die Tatsache berücksichtigen, dass der Computer selbst startet und es einige Zeit dauern kann, bis auf Netzwerkpakete reagiert wird.

Antworten:


11

Ich habe keinen Host, zu dem ich ssh kann und steuern kann, ob er aktiv ist oder nicht, aber das sollte funktionieren:

while ! ssh <ip>
do
    echo "Trying again..."
done

Oder ein Shell-Skript, das expliziter ist:

#!/bin/sh

ssh $1
while test $? -gt 0
do
   sleep 5 # highly recommended - if it's in your local network, it can try an awful lot pretty quick...
   echo "Trying again..."
   ssh $1
done

Speichern Sie es als (sagen wir) waitforssh.shund rufen Sie es dann mit aufsh waitforssh.sh 192.168.2.38


Das funktioniert ziemlich gut! Der Schlaf 5 wird nicht benötigt, da dies alle lokalen Maschinen sind. Vielen Dank!
Weboide

1
Beachten Sie IDS / IPS (Intrusion Detection / Prevention Systems), die dies möglicherweise als SSH-Scan oder Angriff betrachten.
Jason

4

Etwas Einfaches wie dieses erledigt den Job, indem es 5 Sekunden zwischen den Versuchen wartet und STDERR verwirft

until ssh <host> 2> /dev/null
  do
    sleep 5
  done

2
function hurryup () { 
    until ssh -o ConnectTimeout=2 "$1"@"$2"
        do sleep 1
    done
}
hurryup root "10.10.0.3"

-o ConnectTimeout=2ist eine etwas hackige Methode, um nicht auf Netzwerkpakete zu reagieren und zu berichten, ssh: connect to host 10.10.0.3 port 22: Operation timed outbis sie reagiert .

Wenn der Host dann auf Netzwerkpakete reagiert, erfolgt die 1-Sekunden-Pause zwischendurch, ssh: connect to host 10.10.0.3 port 22: Connection refusedwährend wir darauf warten, dass ssh angezeigt wird.


1

Dem Befehl ssh kann ein Befehl zugewiesen werden, der als letzter Parameter auf dem Remotecomputer ausgeführt wird. Rufen Sie also ssh $MACHINE echoin einer Schleife auf. Bei Erfolg wird 0 in $ zurückgegeben, bei Fehler 255. Sie müssen natürlich die paswordless-Authentifizierung mit Zertifikaten verwenden.


1

Nun, ich bin mir nicht sicher, was du damit meinst, wach zu sein , aber was ist mit:

$ ping host.com | grep --line-buffered "bytes from" | head -1 && ssh host.com

Der erste Befehl ping | ... | head -1wartet darauf, dass der Server eine einzelne Ping-Antwort sendet, und ist vorhanden. Dann kommt ssh ins Spiel. Beachten Sie, dass grepdie Ausgabe gepuffert werden kann --line-buffered.

Sie können diesen Befehl mit der Bash-Funktion umschließen, um ihn genau so zu verwenden, wie Sie es beschrieben haben.

$ waitfor() { ping $1 | grep --line-buffered "bytes from" | head -1 }
$ waitfor server.com && ssh server.com

2
Dies wird auf den Server warten, aber nicht auf den Port
Archimedes Trajano

1

Dies ist ein 'ping_ssh'-Skript, das ich verwende. Es behandelt Timeout-Fälle, ist schnell erfolgreich und fordert nicht zur Eingabe von Kennwörtern auf oder lässt sich nicht täuschen, wenn der Port geöffnet ist, aber nicht wie bei 'nc'-basierten Lösungen reagiert. Dies kombiniert mehrere Antworten, die auf verschiedenen Stackoverflow-bezogenen Sites gefunden wurden.

#!/usr/bin/bash
HOST=$1
PORT=$2
#HOST="localhost"
#PORT=8022
if [ -z "$1" ]
  then
    echo "Missing argument for host."
    exit 1 
fi

if [ -z "$2" ]
  then
    echo "Missing argument for port."
    exit 1 
fi
echo "polling to see that host is up and ready"
RESULT=1 # 0 upon success
TIMEOUT=30 # number of iterations (5 minutes?)
while :; do 
    echo "waiting for server ping ..."
    # /server/152795/linux-command-to-wait-for-a-ssh-server-to-be-up
    # /unix/6809/how-can-i-check-that-a-remote-computer-is-online-for-ssh-script-access
    # /programming/1405324/how-to-create-a-bash-script-to-check-the-ssh-connection
    status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 ${HOST} -p ${PORT} echo ok 2>&1)
    RESULT=$?
    if [ $RESULT -eq 0 ]; then
        # this is not really expected unless a key lets you log in
        echo "connected ok"
        break
    fi
    if [ $RESULT -eq 255 ]; then
        # connection refused also gets you here
        if [[ $status == *"Permission denied"* ]] ; then
            # permission denied indicates the ssh link is okay
            echo "server response found"
            break
        fi
    fi
    TIMEOUT=$((TIMEOUT-1))
    if [ $TIMEOUT -eq 0 ]; then
        echo "timed out"
        # error for jenkins to see
        exit 1 
    fi
    sleep 10
done

Ich habe meine PEM-Datei mit -i und meinem Benutzernamen zum SSH-Befehl hinzugefügt, und dieses Skript funktioniert.
David Medinets
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.