it-swarm-ru.tech

Как пинговать в linux, пока не станет известен Host?

Как я могу пинговать определенный адрес и, когда найден, перестать пинговать.

Я хочу использовать его в скрипте bash, поэтому, когда хост запускается, скрипт продолжает пинговать, и с того момента, как хост становится доступным, скрипт продолжается ...

50
Sander Versluys

Дальнейшее упрощение ответа Мартины:

until ping -c1 www.google.com >/dev/null 2>&1; do :; done

обратите внимание, что сам ping используется в качестве проверки цикла; как только это удастся, цикл заканчивается. Тело цикла пустое, с пустой командой ": "используется для предотвращения синтаксической ошибки.

Обновление: я подумал о том, как заставить Control-C аккуратно выйти из цикла проверки связи. Это запустит цикл в фоновом режиме, перехватит сигнал прерывания (Control-C) и уничтожит фоновый цикл, если это произойдет:

ping_cancelled=false    # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" >/dev/null 2>&1; do :; done &    # The "&" backgrounds it
trap "kill $!; ping_cancelled=true" SIGINT
wait $!          # Wait for the loop to exit, one way or another
trap - SIGINT    # Remove the trap, now we're done with it
echo "Done pinging, cancelled=$ping_cancelled"

Это немного сложновато, но если вы хотите, чтобы цикл был отменяемым, он должен сделать свое дело.

87
Gordon Davisson

Вы можете сделать цикл, отправить один пинг и в зависимости от статуса прервать цикл, например (bash):

while true; do ping -c1 www.google.com > /dev/null && break; done

Помещение этого где-то в вашем скрипте будет блокировать, пока www.google.com проверяется.

25
Martynas Saint

Я знаю, что вопрос старый ... и конкретно спрашивает о ping, но я хотел поделиться своим решением.

Я использую это при перезагрузке хостов, чтобы знать, когда я смогу снова подключиться к ним по SSH. (Поскольку ping будет отвечать в течение нескольких секунд, прежде чем sshd будет запущен.)

until nc -vzw 2 $Host 22; do sleep 2; done
22
Aaron Copley

Пингуйте целевой хост один раз. Проверьте, прошел ли пинг (возвращаемое значение пинга равно нулю). Если Хост не жив, снова пингуйте.

Следующий код можно сохранить в виде файла и вызвать с именем хоста в качестве аргумента или удалить из первой и последней строки и использовать в качестве функции в существующем сценарии (имя хоста waitForHost).

Код не оценивает причину сбоя, если эхо-запрос не приводит к ответу, таким образом, зацикливание навсегда, если Хост не существует. Моя справочная страница BSD перечисляет значение каждого возвращаемого значения, в то время как linux нет, поэтому я думаю, что это не может быть переносимым, поэтому я и оставил его.

#!/bin/bash

PING=`which ping`

function waitForHost
{
    if [ -n "$1" ]; 
    then
        waitForHost1 $1;
    else
        echo "waitForHost: Hostname argument expected"
    fi
}

function waitForHost1
{
    reachable=0;
    while [ $reachable -eq 0 ];
    do
    $PING -q -c 1 $1
    if [ "$?" -eq 0 ];
    then
        reachable=1
    fi
    done
    sleep 5
}
waitForHost $1
11
Jan Jungnickel
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 Host &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

Вы можете удалить сон 1, это только здесь, чтобы предотвратить любую проблему затопления в случае, когда Хост будет повторно подключен, но ping не будет выходить с кодом 0.

9
radius

Пожалуйста, смотрите хорошие варианты в stackoverflow . Вот пример в bash, вам придется перебирать следующий код, пока он не вернет успешный результат проверки связи.


ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi
4
Francois Wolmarans

любой из вышеперечисленных циклов также можно использовать с fping, а не с ping, который, IMO, лучше подходит для использования в скриптах, чем сам ping. Смотрите fping (1) для деталей.

while ! fping -q $HOSTNAMES ; do :; done

также полезно для проверки работоспособности машин перед их выполнением. Простой пример:

 для h в Host1 Host2 Host3; сделать 
 если fping -q $ h; затем 
 echo -n "$ h:" 
 ssh $ h "uname -a" 
 fi 
 сделано 
3
cas

Чтобы приятно обрабатывать SIGINT на пинг BSD.

Host=google.com NO=1; while [ $NO -ne 0 ]; do ping -W1 -c1 $Host &>/dev/null; NO=$?;echo "$(date) ($Host) $NO" ; done; echo "$(date) ($Host) reachable"

как функция

ping_until(){
  local NO=1
  while [ $NO -ne 0 ]; do
    ping -W1 -c1 $1 &>/dev/null; NO=$?
    # Optionally block ICMP flooding
    # sleep 1
    echo "$(date) ($1) ($NO)"
  done
}
1
Luke Exton

Это будет пытаться определенное количество раз.

t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r

Вместо того, чтобы повторять $r, вы можете проверить его и действовать в соответствии с его значением:

if ((r)); then echo 'Failed to contact Host'; else echo 'Continuing with script'; fi
1
Paused until further notice.

Для пользователей MacOS ping имеет параметр -o специально для этого:

-o      Exit successfully after receiving one reply packet.

Итак, команда проста:

ping -o www.google.com

Возвращает 0, когда хост успешно пропингован один раз.

1
Melebius

В общем, я хочу дождаться появления своей базы данных или другого сервера, но я не хочу ждать тоже долго. Следующий код ждет 10 секунд, затем устанавливает код выхода, если сервер не появился в течение указанного времени.

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

for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${Host} &>/dev/null && break ; done
0
johntellsall

Я использовал следующую функцию. Мне это нравится, потому что я могу сказать, чтобы он прекратил попытки через некоторое время:

#!/usr/bin/env bash

function networkup {
  # Initialize number of attempts
  reachable=$1
  while [ $reachable -ne 0 ]; do
    # Ping supplied Host
    ping -q -c 1 -W 1 "$2" > /dev/null 2>&1
    # Check return code
    if [ $? -eq 0 ]; then
      # Success, we can exit with the right return code
      echo 0
      return
    fi
    # Network down, decrement counter and try again
    let reachable-=1
    # Sleep for one second
    sleep 1
  done
  # Network down, number of attempts exhausted, quiting
  echo 1
}

Его можно использовать для запуска чего-либо:

# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
  firefox &
fi
0
oneself

Дальнейшее улучшение ответа Гордона Дэвиссона:

until $(ping -c1 www.google.com &>/dev/null); do :; done

с окружающим $ () запускается подоболочка, и поэтому вы можете использовать Control-C, чтобы завершить цикл в случае, если Хост не станет доступным.

0
Shawn