Piszę na skrypcie restartującym różne serwery. Po ponownym uruchomieniu chcę „poczekać”, aż wszystkie serwery powrócą do trybu online. (Dla uproszczenia zdefiniowałem dla niego online = możliwość pingowania)
Tak więc dla każdego serwera
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
Czego bym się spodziewał (i lubił) to wynik taki jak np
waiting for ServerXY .................
ServerXY is back online!
gdzie kropki ... pojawiałyby się jedna po drugiej.
Ale to, co się faktycznie dzieje, jest pierwsze
waiting for ServerXY ...
przez jakiś czas i kiedy serwer powraca, dostaję ostatnią kropkę i ostatnią linię jak
waiting for ServerXY ....
ServerXY is back online!
Dlaczego pętla while jest wykonywana tylko dwa razy, tak jak raz z niepowodzeniem ping i raz z pingiem? Co muszę zmienić, aby dodać więcej kropek w pętli while?
Zrobiłem test również z nieistniejącym adresem IP. Ale utknęło
waiting for NonExistentServer...
i oczywiście nigdy nie wygasły. Ale to samo pytanie, dlaczego nie ........
zostanie dodane?
Odpowiedzi:
Problem
Problem polega na tym, że ustawiłeś
-w 0.2
. Gdy wartość jest mniejsza niż 1, wartości deadline (-w
) i timeout (-W
) są ignorowane. Zostało to wspomniane wcześniej w tym pytaniu . Kiedy używasz-w 1
, twój skrypt (który nieco zmodyfikowałem, aby usunąć niepotrzebne bity) działa poprawnie:Rozwiązanie
Oczywistym rozwiązaniem jest użycie
-w 1
. Jeśli zamierzasz używać wartości mniejszej niż 1 sekunda,timeout
polecenie powinno być lepsze:Ponownie użyj go z
!
operatorem w pętli:Oczywiście odwrotność może być zastosowana do wyświetlania wiadomości tylko wtedy, gdy serwer jest włączony i informuje o awarii serwera, przykład:
Pamiętaj jednak, że nie jest to idealne:
pingujemy przy użyciu tylko 1 pakietu na sekundę. Niska przepustowość, słaba łączność, zły sprzęt między serwerem a klientem pingujący serwer spowoduje wyzwolenie pętli i fałszywe pozytywne powiadomienie
Opieramy się na pingowaniu, czyli wykorzystaniu echa ICMP. Zapory ogniowe, a nawet pojedyncze serwery blokują odpowiedzi na echo ping / ICMP. Można korzystać
nc
zncat
(który jest udoskonaloną wersjąnc
). Coś jak w powyższej pętli będzie działać dobrze zamiastping
:To robi to połączyć się z serwerem na 172.16.127.2 na porcie 80.
-z
to uniknąć I / O - po prostu podłącz i rozłącz.-w
odczeka 5 sekund przed zgłoszeniem nieudanego połączenia. Oczywiście jest to całkiem dobre, gdy masz serwer pod kontrolą i wiesz, że port 80 jest otwarty. Z UPD można dobrze korzystać, ale jeśli zainstalowana jest zapora ogniowa, prawdopodobnie preferowany jest protokół TCP.Ukrytą korzyścią jest to, że jeśli masz usługę działającą na określonym porcie (np. HTTP na porcie 80 lub RTSP na 554), niepowodzenie połączenia z portem może służyć jako wskaźnik, że twoja usługa wymaga ponownego uruchomienia.
Oczywiście
nc
iping
może być trochę spamerski. Lepszym sposobem byłoby zameldowanie się na serwerze z innym serwerem centralnym, wysyłanie okresowego raportu, może co godzinę; w ten sposób, jeśli twój serwer straci „czas uderzenia”, możesz generować błędy. Lepszym sposobem jest skorzystanie z usługi takiej jak Nagios, która to robi. Ale w tym momencie wchodzimy w sferę obliczeń na poziomie przedsiębiorstwa z wieloma serwerami. Jeśli masz w domu coś takiego jak Raspberry Pi, prawdopodobnie nie potrzebujesz niczego złożonego.źródło
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
co wstrzyma się, gdy każdy serwer wróci.