Ich schreibe über ein Skript, das verschiedene Server neu startet. Nach dem Neustart möchte ich "warten", bis alle Server wieder online sind. (Um die Dinge einfach zu halten, habe ich sie online definiert = pingbar)
Also für jeden Server, den ich mache
ServerXY_W=1
echo -n "waiting for ServerXY ..."
while (($ServerXY_W == 1))
do
if ping -c 1 -w 0.2 192.168.123.123 &> /dev/null
then
echo "ServerXY is back online!"
ServerXY_W=0
else
echo -n "."
fi
done
Was ich erwarten würde (und mag), wäre eine Ausgabe wie z
waiting for ServerXY .................
ServerXY is back online!
wo die Punkte ... würden eins nach dem anderen erscheinen.
Aber was tatsächlich passiert, ist, dass es zuerst nur gibt
waiting for ServerXY ...
für eine Weile und wenn der Server zurück ist, bekomme ich den letzten Punkt und die letzte Zeile wie
waiting for ServerXY ....
ServerXY is back online!
Warum wird die while-Schleife nur zweimal ausgeführt, einmal mit fehlgeschlagenem Ping und einmal mit erfolgreichem Ping? Was muss ich ändern, damit mehr Punkte in der while-Schleife hinzugefügt werden?
Ich habe den Test auch mit einer nicht vorhandenen IP durchgeführt. Aber es blieb hängen
waiting for NonExistentServer...
und natürlich nie gekündigt. Aber die gleiche Frage, warum wird das nicht ........
hinzugefügt?
Antworten:
Die Angelegenheit
Das Problem ist, dass Sie eingestellt haben
-w 0.2
. Wenn der Wert unter 1 liegt, werden die Werte für Deadline (-w
) und Timeout (-W
) ignoriert. Dies wurde bereits in dieser Frage erwähnt . Wenn Sie verwenden-w 1
, funktioniert Ihr Skript (das ich leicht modifiziert habe, um nutzlose Bits zu entfernen) ordnungsgemäß:Lösung
Offensichtliche Lösung ist zu verwenden
-w 1
. Wenn Sie einen Wert unter 1 Sekunde verwendentimeout
möchten, sollte der Befehl besser sein:Verwenden Sie es erneut mit dem
!
Operator in der Schleife:Natürlich kann das Gegenteil auf das Anzeigen von Nachrichten nur angewendet werden, wenn der Server aktiv ist, und melden, wenn der Server ausfällt. Beispiel:
Beachten Sie jedoch, dass dies nicht perfekt ist:
Wir pingen mit nur 1 Paket pro Sekunde. Geringe Bandbreite, schlechte Konnektivität und schlechte Hardware zwischen Server und Client, die den Server anpingen, lösen die Schleife aus und führen zu einer falsch positiven Benachrichtigung
Wir verlassen uns auf Ping, das ICMP-Echo verwendet. Firewalls oder sogar einzelne Server blockieren Antworten auf Ping / ICMP-Echo. Sie könnten verwenden
nc
vonncat
(das ist eine verbesserte Version vonnc
). Etwas wie in der obigen Schleife funktioniert einwandfrei anstelle vonping
:Damit wird eine Verbindung zum Server unter 172.16.127.2 auf Port 80 hergestellt.
-z
Um E / A zu vermeiden, müssen Sie nur eine Verbindung herstellen und die Verbindung trennen.-w
Warten Sie 5 Sekunden, bevor Sie eine fehlgeschlagene Verbindung melden. Dies ist natürlich ziemlich gut, wenn Sie den Server unter Ihrer Kontrolle haben und wissen, dass der Port 80 geöffnet ist. UPD kann problemlos verwendet werden, aber wenn eine Firewall vorhanden ist, wird TCP wahrscheinlich bevorzugt.Ein versteckter Vorteil besteht darin, dass, wenn auf einem bestimmten Port ein Dienst ausgeführt wird (z. B. HTTP auf Port 80 oder RTSP auf 554), die Nichtverbindung mit dem Port möglicherweise als Indikator dafür dient, dass Ihr Dienst neu gestartet werden muss.
Natürlich
nc
undping
kann ein bisschen spammig sein. Besser wäre es, wenn der Server bei einem anderen zentralen Server eincheckt und regelmäßig, möglicherweise stündlich, einen Bericht sendet. Auf diese Weise können Sie Fehler generieren, wenn Ihr Server eine "Punch Time" verpasst. Besser ist es, einen Dienst wie Nagios zu nutzen, der das tut. An diesem Punkt betreten wir jedoch den Bereich des Computing auf Unternehmensebene mit mehreren Servern. Wenn Sie so etwas wie Raspberry Pi zu Hause haben, brauchen Sie wahrscheinlich nichts Komplexes.quelle
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
was gilt, wenn jeder Server zurück ist.