Estoy escribiendo en un script que reinicia varios servidores. Después del reinicio quiero "esperar" hasta que todos los servidores vuelvan a estar en línea. (Para simplificar las cosas, lo definí en línea = pingable)
Entonces, para cada servidor que hago
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
Lo que esperaría (y me gustaría) sería una salida como, por ejemplo,
waiting for ServerXY .................
ServerXY is back online!
donde los puntos ... aparecerían uno por uno.
Pero lo que realmente sucede es que primero solo hay
waiting for ServerXY ...
por un tiempo y cuando el servidor está de vuelta, obtengo el último punto y la última línea como
waiting for ServerXY ....
ServerXY is back online!
¿Por qué el bucle while solo se realiza dos veces como una vez con un error de ping y una vez con ping exitoso? ¿Qué debo cambiar para agregar más puntos en el ciclo while?
Hice la prueba también con una IP inexistente. Pero se quedó atascado con
waiting for NonExistentServer...
y nunca terminado por supuesto. Pero la misma pregunta ¿por qué no ........
se agregan?
Respuestas:
La cuestión
El problema es que lo has configurado
-w 0.2
. Cuando el valor es inferior a 1, se ignoran los valores de fecha límite (-w
) y tiempo de espera (-W
). Esto ha sido mencionado previamente en esta pregunta . Cuando lo usa-w 1
, su script (que modifiqué un poco para eliminar bits inútiles) funciona correctamente:Solución
La solución obvia es usar
-w 1
. Si tiene la intención de utilizar un valor inferior a 1 segundo, eltimeout
comando debería ser mejor:Nuevamente, úselo con el
!
operador en el bucle:Por supuesto, lo contrario se puede aplicar para mostrar el mensaje solo si el servidor está activo e informar cuando el servidor se cae, por ejemplo:
Sin embargo, tenga en cuenta que esto no es perfecto:
hacemos ping con solo 1 paquete por segundo. Ancho de banda bajo, conectividad deficiente, hardware defectuoso entre el servidor y el cliente que hace ping al servidor activará la salida del bucle y hará una notificación de falsos positivos
Confiamos en hacer ping, es decir, usar el eco ICMP. Los cortafuegos o incluso los servidores individuales bloquean las respuestas al eco de ping / ICMP. Usted podría utilizar
nc
dencat
(que es una versión mejorada delnc
). Algo como en el bucle anterior funcionará bien en lugar deping
:Lo que esto hace es conectarse al servidor en 172.16.127.2 en el puerto 80.
-z
es evitar E / S, solo conéctese y desconecte.-w
es esperar 5 segundos antes de informar una conexión fallida. Por supuesto, esto es bastante bueno para cuando tiene el servidor bajo su control y sabe que el puerto 80 está abierto. UPD se puede usar bien, pero si hay un firewall en su lugar, probablemente se prefiera TCP.Un beneficio oculto aquí es que si tiene algún servicio ejecutándose en un puerto específico (como HTTP en el puerto 80 o RTSP en 554), no conectarse al puerto puede servir como indicador de que su servicio necesita reiniciarse.
Por supuesto,
nc
yping
puede ser un poco spam. La mejor manera sería hacer que el servidor se registre con otro servidor central, enviar un informe periódico, tal vez cada hora; de esa manera, si su servidor pierde un "tiempo de perforación", puede generar errores. La mejor manera es usar un servicio como Nagios, que hace eso. Pero en este punto estamos entrando en el ámbito de la informática de nivel empresarial con múltiples servidores. Si tienes algo como Raspberry Pi en casa, probablemente no necesites nada complejo.fuente
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
que se mantiene cuando cada servidor está de vuelta.