Як я можу ввести певну адресу і, коли її знайдуть, припиніть писати.
Я хочу використовувати його в скрипті bash, тому коли хост запускається, сценарій продовжує писати, і з моменту появи хоста сценарій продовжується ...
Як я можу ввести певну адресу і, коли її знайдуть, припиніть писати.
Я хочу використовувати його в скрипті bash, тому коли хост запускається, сценарій продовжує писати, і з моменту появи хоста сценарій продовжується ...
Відповіді:
Подальше спрощення відповіді Мартинаса:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
зауважте, що сам ping використовується як цикл тестування; як тільки це вдається, петля закінчується. Тіло циклу порожнє, з нульовою командою " :
" використовується для запобігання синтаксичної помилки.
Оновлення: я продумав спосіб змусити Control-C вийти з циклу ping чисто. Це запустить цикл у фоновому режимі, захопить сигнал переривання (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
вбити його.
Ви можете зробити цикл, надіслати один ping і, в залежності від стану, перервіть цикл, наприклад (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Якщо розмістити це десь у вашому сценарії, він буде заблокований, поки www.google.com
не з'явиться pingable.
while true
і break
є чистішим рішенням, ІМО.
while true; do sleep 5; ping ...
Я знаю, що питання давнє ... і конкретно запитує щодо ping
, але я хотів поділитися своїм рішенням.
Я використовую це під час перезавантаження хостів, щоб знати, коли я можу SSH знову в них. (Оскільки ping
відповість буде за кілька секунд до sshd
початку роботи.)
until nc -vzw 2 $host 22; do sleep 2; done
Один раз відправте цільовий хост. Перевірте, чи ping вдався (повернене значення ping дорівнює нулю). Якщо хост не живий, знову пінг.
Наступний код можна зберегти як файл і викликати з ім'ям хосту як аргумент, або позбавити першого та останнього рядка та використовувати як функцію в межах існуючого сценарію (waitForHost ім'я хоста).
Код не оцінює причину відмови, якщо ping не призведе до відповіді, таким чином, назавжди циклічно, якщо хост не існує. Моя сторінка 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
Будь ласка, дивіться хороші варіанти на stackoverflow . Ось зразок в bash, вам доведеться перебирати наступний код, поки він не поверне успішний результат ping.
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
також корисно для тестування, якщо машини стоять, перш ніж робити щось на них. Простий приклад:
за год у HOST1 HOST2 HOST3; робити якщо fping -q $ h; тоді відлуння -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 ping.
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