Bash ожидает успеха ping

Я пишу на сценарии, перезагружающем различный Сервер. После перезагрузки я хочу "ожидать", пока весь Сервер назад не онлайн. (Для хранения вещей простыми, я определил для меня online=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!

Почему цикл с условием продолжения только выполняется дважды как однажды со сбоем ping и однажды со следованием ping? Что я должен изменить для получения большего количества точек, добавленных в цикле с условием продолжения?

Я сделал тест также с не существующим IP. Но это застряло с

waiting for NonExistentServer...

и никогда завершаемый, конечно. Но тот же вопрос, почему не делают ........ быть добавленными?

9
задан 27 June 2017 в 09:33

1 ответ

Проблема

Проблема состоит в том, что Вы установили -w 0.2. Когда значение ниже 1, крайний срок (-w) и тайм-аут (-W) значения проигнорированы. Это было упомянуто ранее в этом вопросе. Когда Вы используете -w 1 , Ваш сценарий (который я немного изменил для удаления бесполезных битов), работы правильно:

$ ./ping_server.sh                                                 
waiting for ServerXY ....................
Server is back online

$ cat ./ping_server.sh
#!/bin/bash
printf "%s" "waiting for ServerXY ..."
while ! ping -c 1 -n -w 1 147.153.237.192 &> /dev/null
do
    printf "%c" "."
done
printf "\n%s\n"  "Server is back online"

Решение

Очевидное решение состоит в том, чтобы использовать -w 1. Если Вы действительно предназначаете при использовании значения ниже, чем 1 секунда, timeout команда должна быть лучше:

$ timeout 0.2 ping -c 1 147.153.237.192                            
PING 147.153.237.192 (147.153.237.192) 56(84) bytes of data.
64 bytes from 147.153.237.192: icmp_seq=1 ttl=124 time=2.61 ms

--- 147.153.237.192 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.612/2.612/2.612/0.000 ms

Снова, используйте его с ! оператор в цикле:

#!/bin/bash
printf "%s" "waiting for ServerXY ..."
while ! timeout 0.2 ping -c 1 -n 147.153.237.192 &> /dev/null
do
    printf "%c" "."
done
printf "\n%s\n"  "Server is back online"

Конечно, противоположное может быть применено к показу сообщения, только если сервер возрос, и сообщите, когда сервер понижается, пример:

$ while ping -q -c 1 172.16.127.2 >/dev/null ; do sleep 1; done ; echo "Server stopped responding"
Server stopped responding

Отметьте однако, это не прекрасно:

  • мы проверяем с помощью ping-запросов со всего 1 пакетом каждую секунду. Низкая пропускная способность, плохая возможность соединения, неисправное оборудование, промежуточное сервер и клиент, проверяющий с помощью ping-запросов сервер, инициируют цикл, чтобы выйти и сделать ложное положительное уведомление

  • Мы полагаемся на проверку с помощью ping-запросов, которая использует эхо ICMP. Брандмауэры или даже отдельные ответы блока серверов на эхо ping/ICMP. Вы могли использовать nc из ncat (который является улучшенной версией nc). Что-то как в цикле выше будет хорошо работать вместо ping:

    nc -w5 -z 172.16.127.2 80
    

    То, что это делает, соединиться с сервером на 172.16.127.2 на порте 80. -z должен избежать, чтобы ввод-вывод - просто соединился и разъединился. -w должен ожидать в течение 5 секунд прежде, чем сообщить об отказавшем соединении. Конечно, это - довольно хорошее для того, когда у Вас есть сервер под Вашим управлением, и Вы знаете, что порт 80 открыт. UPD может использоваться прекрасный, но если там существует брандмауэр, TCP, вероятно, предпочтен.

    Скрытое преимущество здесь - то, что, если у Вас есть некоторый сервис, работающий на определенном порте (таком как HTTP на порте 80 или RTSP на 554), не удаваясь соединиться с портом, может служить индикатором, для Вашего сервиса нужен перезапуск.

  • Конечно, nc и ping может быть немного спамным. Лучший путь состоял бы в том, чтобы иметь регистрацию сервера с другим центральным сервером, отправить регулярный доклад, возможно, каждый час; тот путь, если Ваш сервер пропускает "время перфорации" Вы, может генерировать ошибки. Лучший путь состоит в том, чтобы использовать службу, такую как Nagios, который делает это. Но в этой точке мы входим в область вычислений уровня предприятия с несколькими серверами. Если у Вас есть что-то как Raspberry Pi дома, Вам, вероятно, не нужно ничто сложное.

8
ответ дан 23 November 2019 в 05:05

Другие вопросы по тегам:

Похожие вопросы: