Frage Wie in Linux pingen, bis der Host bekannt ist?


Wie kann ich eine bestimmte Adresse anpingen und wenn sie gefunden wird, höre auf zu pingen.

Ich möchte es in einem Bash-Skript verwenden. Wenn der Host gestartet wird, klingelt das Skript weiter und ab dem Moment, in dem der Host verfügbar ist, wird das Skript fortgesetzt ...


42
2017-07-17 07:45


Ursprung




Antworten:


Eine weitere Vereinfachung von Martynas 'Antwort:

until ping -c1 www.google.com &>/dev/null; do :; done

Beachten Sie, dass Ping selbst als Loop-Test verwendet wird; Sobald es gelingt, endet die Schleife. Der Schleifenkörper ist leer, mit dem Null-Befehl ":"um einen Syntaxfehler zu vermeiden.

Update: Ich habe mir einen Weg ausgedacht, wie Control-C die Ping-Schleife sauber verlassen kann. Dies führt die Schleife im Hintergrund aus, fängt das Interrupt-Signal (Control-C) ein und löscht die Hintergrundschleife, falls sie auftritt:

ping_cancelled=false    # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" &>/dev/null; do :; done &    # The "&" backgrounds it
trap "kill $!; ping_cancelled=true" SIGINT
wait $!          # Wait for the loop to exit, one way or another
trap - SIGINT    # Remove the trap, now we're done with it
echo "Done pinging, cancelled=$ping_cancelled"

Es ist ein wenig umständlich, aber wenn Sie möchten, dass die Schleife abbrechbar ist, sollte es den Trick tun.


77
2017-07-17 23:16



Um 'Schlaf' hinzuzufügen (z.B. alle 5 Sekunden): while! ping -c1 www.google.com &> / dev / null; Schlaf 5; erledigt - lepe
Perfekt! Funktioniert auch unter Mac OSX. - Bart Kummel
Standardmäßig ping wird 10 Sekunden warten, bevor er seinen Ping aufgibt. Wenn Sie das auf 1 Sekunde reduzieren möchten, können Sie verwenden -w1. - Jack O'Connor
@ JackO'Connor Mit BSD-Ping ist dies ein Kapital -W1 - Luke Exton
Mein einziges Problem mit dieser Antwort ist, dass es SIGINT nicht gut beherrscht. Sie können dies nicht über die Befehlszeile stoppen, wenn es aus irgendeinem Grund nie eine Verbindung herstellen wird. - Luke Exton


Sie können eine Schleife ausführen, einen Ping senden und je nach Status die Schleife unterbrechen, zum Beispiel (bash):

while true; do ping -c1 www.google.com > /dev/null && break; done

Wenn Sie das irgendwo in Ihrem Skript platzieren, wird es blockiert www.google.com ist pingbar.


22
2017-07-17 08:01



Diese while true und break ist die sauberere Lösung, IMO. - Dan Carley
@DanCarley Ich werde dir nicht zustimmen, aus dem Grund, dass in der akzeptierten Antwort, der Null-Befehlsversion, man einen Schlaf / Warte-Modus einsetzen könnte, um der CPU eine Pause zu geben, und in diesem Fall würde ich die sauberere Lösung nennen. Das andere Problem mit dieser Antwort besteht darin, dass der Leser / Benutzer verstehen muss, wie && funktioniert, und wie das geschieht, wenn der erste Befehl fehlschlägt, wird er nicht aufgerufen. Dies ist nur eine Meinung, wie deine eigene. - Hamid
Der Hauptunterschied, den ich zwischen dieser Lösung und der akzeptierten sehe, ist, dass diese die Fehlermeldung "unbekannter Host ..." zurückgibt, bis sie gefunden wird. Hinzufügen schlafen (z.B. alle 5 Sekunden): while true; do sleep 5; ping ... - lepe


Ich weiß, die Frage ist alt ... und fragt speziell nach ping, aber ich wollte meine Lösung teilen.

Ich benutze das beim Neustart von Hosts, um zu wissen, wann ich wieder in sie SSH kann. (Schon seit ping wird für einige Sekunden zuvor antworten sshd ist gestartet.)

until nc -vzw 2 $host 22; do sleep 2; done

17
2017-10-11 14:37



Genau das habe ich gesucht, danke! Sie können den Anruf sogar mit STRG + C unterbrechen, was bei einigen anderen Lösungen in diesem Thread nicht der Fall ist. - Alex
Beachten Sie, dass dies für BSD-Versionen von netcat funktioniert. Die nmap.org-Version in Linux-Distributionen ist anders implementiert, so dass die Option -z nicht existiert und die Option -w auf eine Verbindung wartet, aber nicht schließt, wenn sie erfolgreich ist. Funktioniert in OSX jedoch gut. - Paul


Pingen Sie den Zielhost einmal an. Überprüfen Sie, ob der Ping erfolgreich war (Rückgabewert von Ping ist Null). Wenn der Host nicht aktiv ist, erneut pingen.

Der folgende Code kann als Datei gespeichert und mit dem Hostnamen als Argument aufgerufen werden oder die erste und letzte Zeile wird entfernt und als Funktion innerhalb eines vorhandenen Skripts (waitForHost hostname) verwendet.

Der Code wertet die Fehlerursache nicht aus, wenn der Ping nicht zu einer Antwort führt und somit für immer eine Schleife auftritt, wenn der Host nicht existiert. Meine BSD-Manpage listet die Bedeutung jedes Rückgabewerts auf, während der Linux-Manual dies nicht tut, also denke ich, dass dies möglicherweise nicht tragbar ist, deshalb habe ich es weggelassen.

#!/bin/bash

PING=`which ping`

function waitForHost
{
    if [ -n "$1" ]; 
    then
        waitForHost1 $1;
    else
        echo "waitForHost: Hostname argument expected"
    fi
}

function waitForHost1
{
    reachable=0;
    while [ $reachable -eq 0 ];
    do
    $PING -q -c 1 $1
    if [ "$?" -eq 0 ];
    then
        reachable=1
    fi
    done
    sleep 5
}
waitForHost $1

11
2017-07-17 07:58





UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

Sie können sleep 1 entfernen, es dient nur dazu, Überflutungsprobleme zu vermeiden, falls der Host reachable wäre, aber ping nicht mit Code 0 beendet wird.


9
2017-07-17 08:09





Bitte beachten Sie die guten Optionen unter Paketüberfluss. Hier ist ein Beispiel in bash, Sie müssen den folgenden Code durchlaufen, bis er ein erfolgreiches Ping-Ergebnis zurückgibt.


ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi


4
2017-07-17 08:00





Jede der obigen Schleifen kann auch mit fping anstelle von ping verwendet werden, was IMO besser für die Verwendung in Skripten geeignet ist als Ping selbst. Sehen fping (1) für Details.

while ! fping -q $HOSTNAMES ; do :; done

Dies ist auch nützlich, um zu testen, ob Maschinen aktiv sind, bevor Sie etwas an ihnen vornehmen. Ein einfaches Beispiel:

für h in HOST1 HOST2 HOST3; tun
  wenn fping -q $ h; dann
     echo -n "$ h:"
     ssh $ h "uname -a"
  fi
erledigt

3
2017-07-18 23:25





Dies wird eine bestimmte Anzahl von Malen versuchen.

t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r

Anstatt zu widerhallen $r, Sie können es testen und entsprechend seinem Wert handeln:

if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi

1
2018-06-26 02:06





Um das SIGINT auf BSD-Ping gut zu behandeln.

HOST=google.com NO=1; while [ $NO -ne 0 ]; do ping -W1 -c1 $HOST &>/dev/null; NO=$?;echo "$(date) ($HOST) $NO" ; done; echo "$(date) ($HOST) reachable"

als eine Funktion

ping_until(){
  local NO=1
  while [ $NO -ne 0 ]; do
    ping -W1 -c1 $1 &>/dev/null; NO=$?
    # Optionally block ICMP flooding
    # sleep 1
    echo "$(date) ($1) ($NO)"
  done
}

1
2018-03-31 19:24