Как я могу пинговать определенный адрес и, когда найден, перестать пинговать.
Я хочу использовать его в скрипте bash, поэтому, когда хост запускается, скрипт продолжает пинговать, и с момента доступности хоста скрипт продолжается ...
Как я могу пинговать определенный адрес и, когда найден, перестать пинговать.
Я хочу использовать его в скрипте bash, поэтому, когда хост запускается, скрипт продолжает пинговать, и с момента доступности хоста скрипт продолжается ...
Ответы:
Дальнейшее упрощение ответа Мартины:
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"
Это немного сложновато, но если вы хотите, чтобы цикл был отменяемым, он должен сделать свое дело.
ping
будет ждать 10 секунд, прежде чем отказаться от своего пинга. Если вы хотите уменьшить это до 1 секунды, вы можете использовать -w1
.
-W1
kill %1
убить его.
Вы можете сделать цикл, отправить один пинг и в зависимости от статуса прервать цикл, например (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Размещение этого где-то в вашем скрипте будет блокировать, пока не www.google.com
станет доступным
while true
и break
есть более чистое решение, ИМО.
while true; do sleep 5; ping ...
Я знаю, что вопрос старый ... и конкретно спрашивает относительно ping
, но я хотел поделиться своим решением.
Я использую это при перезагрузке хостов, чтобы знать, когда я смогу снова подключиться к ним по SSH. (Так ping
как ответит за несколько секунд до sshd
запуска.)
until nc -vzw 2 $host 22; do sleep 2; done
Пингуйте целевой хост один раз. Проверьте, прошел ли пинг (возвращаемое значение пинга равно нулю). Если хост не жив, снова пропингуйте.
Следующий код можно сохранить в виде файла и вызвать с именем хоста в качестве аргумента или удалить из первой и последней строки и использовать в качестве функции в существующем сценарии (имя хоста 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
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ];
do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done
Вы можете удалить сон 1, это только здесь, чтобы предотвратить любую проблему с переполнением в случае, когда хост будет повторно подключен, но ping не будет выходить с кодом 0.
Пожалуйста, смотрите хорошие варианты в 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
Любой из вышеперечисленных циклов также можно использовать с 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" фи сделанный
Это будет пытаться определенное количество раз.
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
Чтобы приятно обрабатывать 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
}
Я использовал следующую функцию. Мне это нравится, потому что я могу сказать, чтобы через некоторое время перестать пытаться:
#!/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
В общем, я хочу дождаться появления своей базы данных или другого сервера, но я не хочу ждать слишком долго. Следующий код ждет 10 секунд, а затем устанавливает код выхода, если сервер не появился в течение указанного времени.
Если сервер появится раньше установленного срока, цикл будет закорочен, чтобы можно было запустить следующий бит кода.
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done