Я пишу сценарий перезагрузки различных серверов. После перезагрузки я хочу «подождать», пока все серверы снова не подключатся. (Для простоты я определил для себя онлайн = pingable)
Так что для каждого сервера я делаю
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
То, что я ожидал (и хотел бы), было бы как например
waiting for ServerXY .................
ServerXY is back online!
где точки .... появится один за другим.
Но то, что на самом деле происходит, во-первых, есть только
waiting for ServerXY ...
на некоторое время и когда сервер вернулся, я получаю последнюю точку и последнюю строку, как
waiting for ServerXY ....
ServerXY is back online!
Почему цикл while выполняется только два раза, как один раз с ошибкой ping и один раз с успешной проверкой ping? Что мне нужно изменить, чтобы добавить больше точек в цикл while?
Я сделал тест также с несуществующим IP. Но это застряло с
waiting for NonExistentServer...
и никогда не прекращается, конечно. Но тот же вопрос, почему не ........
добавили?
Ответы:
Проблема
Проблема в том, что вы установили
-w 0.2
. Когда значение меньше 1, значения deadline (-w
) и timeout (-W
) игнорируются. Это было упомянуто ранее в этом вопросе . Когда вы используете-w 1
, ваш скрипт (который я немного изменил, чтобы удалить ненужные биты) работает правильно:Решение
Очевидным решением является использование
-w 1
. Если вы намерены использовать значение меньше 1 секунды,timeout
команда должна быть лучше:Опять же, используйте его с
!
оператором в цикле:Конечно, обратное может быть применено к отображению сообщения только в том случае, если сервер работает и сообщает, когда сервер отключается, например:
Обратите внимание, что это не идеально:
мы пингуем всего 1 пакет в секунду. Низкая пропускная способность, плохая связь, плохое оборудование между сервером и клиентом, проверяющим связь с сервером, вызовет выход из цикла и выдаст ложное положительное уведомление
Мы полагаемся на пинг, который использует эхо ICMP. Брандмауэры или даже отдельные серверы блокируют ответы на эхо-запросы ping / ICMP. Вы можете использовать
nc
изncat
(который является улучшенной версиейnc
). Нечто подобное в цикле выше будет нормально работать вместоping
:Для этого нужно подключиться к серверу на 172.16.127.2 через порт 80.
-z
Избежать ввода-вывода - просто подключиться и отключиться.-w
это подождать 5 секунд, прежде чем сообщать о сбое соединения. Конечно, это очень хорошо, когда сервер находится под вашим контролем и вы знаете, что порт 80 открыт. UPD может использоваться нормально, но если есть брандмауэр, TCP, вероятно, предпочтительнее.Скрытое преимущество заключается в том, что если у вас есть какая-либо служба, работающая на определенном порту (например, HTTP на порту 80 или RTSP на 554), невозможность подключения к порту может служить индикатором, что ваша служба нуждается в перезапуске.
Конечно,
nc
иping
может быть немного спамом. Лучше было бы зарегистрировать сервер на другом центральном сервере, отправлять периодический отчет, возможно, каждый час; таким образом, если ваш сервер пропустит «время удара», вы можете генерировать ошибки. Лучше всего использовать такой сервис, как Nagios, который это делает. Но в этот момент мы попадаем в область вычислений корпоративного уровня с несколькими серверами. Если у вас дома есть что-то вроде Raspberry Pi, вам, вероятно, не нужно ничего сложного.источник
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
что будет, когда каждый сервер вернется.