Wie kann ich eine bestimmte Adresse anpingen und beim Auffinden aufhören zu pingen?
Ich möchte es in einem Bash-Skript verwenden. Wenn der Host gestartet wird, pingt das Skript weiter und sobald der Host verfügbar ist, wird das Skript fortgesetzt.
Wie kann ich eine bestimmte Adresse anpingen und beim Auffinden aufhören zu pingen?
Ich möchte es in einem Bash-Skript verwenden. Wenn der Host gestartet wird, pingt das Skript weiter und sobald der Host verfügbar ist, wird das Skript fortgesetzt.
Antworten:
Eine weitere Vereinfachung der Antwort von Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
Beachten Sie, dass Ping selbst als Schleifentest verwendet wird. Sobald es erfolgreich ist, endet die Schleife. Der Schleifenkörper ist leer, wobei der Befehl " :
" null verwendet wird, um einen Syntaxfehler zu verhindern.
Update: Ich habe mir überlegt, wie Control-C die Ping-Schleife sauber verlassen kann. Dadurch wird die Schleife im Hintergrund ausgeführt, das Interrupt-Signal (Control-C) abgefangen und die Hintergrundschleife beendet, falls dies auftritt:
ping_cancelled=false # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" >/dev/null 2>&1; 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 bisschen umständlich, aber wenn Sie möchten, dass die Schleife stornierbar ist, sollte es den Trick tun.
ping
wird 10 Sekunden gewartet, bevor der Ping aufgegeben wird. Wenn Sie dies auf 1 Sekunde reduzieren möchten, können Sie verwenden -w1
.
-W1
kill %1
es dann.
Sie können eine Schleife erstellen, 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 dies irgendwo in Ihr Skript www.google.com
einfügen, wird dies blockiert, bis Ping möglich ist.
while true
und break
die sauberere Lösung, IMO.
while true; do sleep 5; ping ...
Ich weiß, die Frage ist alt ... und fragt speziell nach ping
, aber ich wollte meine Lösung teilen.
Ich benutze dies, wenn ich Hosts neu starte, um zu wissen, wann ich wieder in sie SSH kann. (Da ping
wird für einige Sekunden reagiert, bevor sshd
gestartet wird.)
until nc -vzw 2 $host 22; do sleep 2; done
Pingen Sie den Zielhost einmal. Überprüfen Sie, ob der Ping erfolgreich war (Rückgabewert von Ping ist Null). Wenn der Host nicht am Leben ist, pingen Sie erneut.
Der folgende Code kann als Datei gespeichert und mit dem Hostnamen als Argument aufgerufen oder von der ersten und letzten Zeile befreit und als Funktion in einem vorhandenen Skript (waitForHost-Hostname) verwendet werden.
Der Code wertet die Fehlerursache nicht aus, wenn der Ping nicht zu einer Antwort führt. Wenn der Host nicht vorhanden ist, wird eine Endlosschleife ausgeführt. Meine BSD-Manpage listet die Bedeutung der einzelnen Rückgabewerte auf, während die Linux-Manpage dies nicht tut. Deshalb habe ich sie 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
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ];
do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done
Sie können den Ruhezustand 1 entfernen. Er dient nur dazu, Überschwemmungsprobleme zu vermeiden, wenn der Host erreichbar ist, Ping jedoch nicht mit Code 0 beendet wird.
Bitte sehen Sie gute Optionen bei Stackoverflow . Hier ist ein Beispiel in Bash. Sie müssen den folgenden Code durchlaufen, bis ein erfolgreiches Ping-Ergebnis zurückgegeben wird.
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
Jede der obigen Schleifen kann auch mit fping anstelle von ping verwendet werden. IMO ist für die Verwendung in Skripten besser geeignet als Ping. Siehe fping (1) für Details.
while ! fping -q $HOSTNAMES ; do :; done
Auch nützlich, um zu testen, ob die Maschinen in Betrieb sind, bevor Sie etwas an ihnen tun. Ein einfaches Beispiel:
für h in HOST1 HOST2 HOST3; machen if fping -q $ h; dann echo -n "$ h:" ssh $ h "uname -a" fi getan
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 wiederholen $r
, können Sie es testen und entsprechend seinem Wert handeln:
if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi
Um mit dem SIGINT auf BSD-Ping gut umzugehen.
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
}
Ich habe die folgende Funktion verwendet. Ich mag es, weil ich sagen kann, dass es nach einer Weile aufhören soll, es zu versuchen:
#!/usr/bin/env bash
function networkup {
# Initialize number of attempts
reachable=$1
while [ $reachable -ne 0 ]; do
# Ping supplied host
ping -q -c 1 -W 1 "$2" > /dev/null 2>&1
# Check return code
if [ $? -eq 0 ]; then
# Success, we can exit with the right return code
echo 0
return
fi
# Network down, decrement counter and try again
let reachable-=1
# Sleep for one second
sleep 1
done
# Network down, number of attempts exhausted, quiting
echo 1
}
Es kann so benutzt werden, um etwas zu starten:
# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
firefox &
fi
Im Allgemeinen möchte ich warten, bis meine Datenbank oder ein anderer Server hochgefahren ist, aber ich möchte nicht zu lange warten . Der folgende Code wartet 10 Sekunden und legt dann den Beendigungscode fest, wenn der Server nicht innerhalb des Zeitlimits angezeigt wurde.
Wenn der Server vor dem Zeitlimit angezeigt wird, wird die Schleife kurzgeschlossen, damit das nächste Codebit ausgeführt werden kann.
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done