Estou escrevendo em um script reiniciando vários servidores. Após a reinicialização, quero "esperar" até que todos os servidores estejam novamente online. (Para simplificar, eu defini para mim on-line = pingável)
Então, para cada servidor que eu faço
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
O que eu esperaria (e gostaria) seria uma saída como por exemplo
waiting for ServerXY .................
ServerXY is back online!
onde os pontos .... apareceriam um por um.
Mas o que realmente acontece é primeiro, há apenas
waiting for ServerXY ...
por um tempo e quando o servidor está de volta eu recebo o último ponto e a última linha como
waiting for ServerXY ....
ServerXY is back online!
Por que o loop while é executado apenas duas vezes como uma vez com falha no ping e uma vez com êxito no ping? O que preciso alterar para adicionar mais pontos no loop while?
Eu fiz o teste também com um IP inexistente. Mas ficou preso com
waiting for NonExistentServer...
e nunca terminou, é claro. Mas a mesma pergunta, por que não ........
são adicionados?
Respostas:
O problema
O problema é que você definiu
-w 0.2
. Quando o valor estiver abaixo de 1, os valores de prazo (-w
) e timeout (-W
) serão ignorados. Isso foi mencionado anteriormente nesta pergunta . Quando você usa-w 1
, seu script (que eu modifiquei levemente para remover bits inúteis) funciona corretamente:Solução
Solução óbvia é usar
-w 1
. Se você pretende usar um valor menor que 1 segundo, otimeout
comando deve ser melhor:Novamente, use-o com o
!
operador no loop:Obviamente, o oposto pode ser aplicado para mostrar a mensagem apenas se o servidor estiver ativo e reportar quando o servidor estiver inativo, por exemplo:
Observe no entanto, isso não é perfeito:
estamos fazendo ping com apenas 1 pacote a cada segundo. Baixa largura de banda, conectividade ruim, hardware ruim entre o servidor e o cliente que executa ping no servidor acionará o loop para sair e fará uma notificação de falso positivo
Estamos confiando no ping, que está usando o eco ICMP. Firewalls ou mesmo servidores individuais bloqueiam as respostas ao eco de ping / ICMP. Você poderia usar
nc
dencat
(que é uma versão melhorada donc
). Algo como no loop acima funcionará bem em vez deping
:O que isso faz é conectar-se ao servidor na 172.16.127.2 na porta 80.
-z
é evitar a E / S - basta conectar e desconectar.-w
é aguardar 5 segundos antes de relatar falha na conexão. Claro que isso é muito bom para quando você tem um servidor sob seu controle e sabe que a porta 80 está aberta. O UPD pode ser usado bem, mas se houver firewall, provavelmente o TCP é o preferido.Um benefício oculto aqui é que, se você tiver algum serviço em execução em uma porta específica (como HTTP na porta 80 ou RTSP em 554), a falha na conexão à porta poderá servir como indicador de que seu serviço precisa ser reiniciado.
Claro,
nc
eping
pode ser um pouco spam. A melhor maneira seria fazer o check-in do servidor com outro servidor central, enviar um relatório periódico, talvez a cada hora; Dessa forma, se o servidor perder um "tempo de espera", você poderá gerar erros. A melhor maneira é usar um serviço como o Nagios, que faz isso. Mas neste momento estamos entrando no domínio da computação em nível corporativo com vários servidores. Se você tem algo como Raspberry Pi em casa, provavelmente não precisa de nada complexo.fonte
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
que ocorre quando todos os servidores estão de volta.