LINUX.ORG.RU
ФорумAdmin

Проверка наличия соединения с интернетом


3

4

Необходимо проверять наличие подключения к интернету и если оно на время пропадало, то выполнять определённую команду. Причём физически компьютер подключен к интернету через роутер, поэтому проводное подключение никуда не пропадает.

Пока напрашивается идея пинговать гугл (точнее его DNS 8.8.8.8, чтобы не тратить времени на разрешение доменного имени) с интервалом 5-10 секунд (нужна хорошая скорость реакции) и, если наступает таймаут (надо как-то ещё прибивать пинг, если нет ответа пару секунд, а то он сам выкинет ошибку слишком поздно).

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

Или вдруг уже существуют готовые решения и мне не надо велосипедить?

P.S.: Пока есть такая идея: для CRON интервал слишком маленький, поэтому сделать скрипт такого содержания и запускать его после загрузки системы:

1. Выполнить пинг. Сохранить в переменную результат (был ли ответ за 2 секунды или нет).

2. Сравнить эту переменную с другой переменной. Если есть отличие (сейчас всё ок, а раньше интернета не было), то выполнить команду.

3. Записать в ту, другую, переменную текущее значение.

4. Уснуть на 10 секунд и перейти к началу цикла.

Вопрос в том как выполнить пункт 1 и правильна ли моя идея (нет ли варианта получше).

P.P.S.: Написал такой скрипт:

#!/bin/bash

last_state=1

while true; do
        ping -c 1 -W 2 8.8.8.8 > /dev/null
        state=$?
        if [ "$last_state" -ne "$state" ]; then
                if [ "$state" -eq "0" ]; then
                        echo "Internet connected!"
                else
                        echo "Internet disconnected!"
                fi
        fi
        last_state=$state
        sleep 10s
done

Правильно ли так делать и нет ли варианта получше?

★★★★★

Последнее исправление: KivApple (всего исправлений: 4)

надо как-то ещё прибивать пинг, если нет ответа пару секунд

man ping, параметр -w

Как это идеалогически верно сделать, чтобы поменьше ресурсов жрало?

Да нормальная идея

ping -c 1 -W 2 8.8.8.8 > /dev/null
state=$?

Я то-то в мане ping не нашел какие значения он возвращает. Я бы парсил вывод ping:

STATUS=`ping 8.8.8.8 -c 1 -w 2 | grep " 1 received"`

if [[ -z "$STATUS" ]]; then
  echo "Интернета нет"
else
  echo "Интернет есть"
fi

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

Ну... если он вернул 0, то ошибки не было, иначе - была. Как и со всеми другими программами. Не?

KivApple ★★★★★
() автор топика
Ответ на: комментарий от schizoid

Физически соединение никуда не исчезает, кабель постоянно воткнут.

KivApple ★★★★★
() автор топика

-c1 будет много ложных срабатываний. советую -c5

Bers666 ★★★★★
()
Ответ на: комментарий от KivApple

Ну... если он вернул 0, то ошибки не было, иначе - была. Как и со всеми другими программами. Не?

Ну, если ты в этом 100% уверен, делай так. Я нигде такого описания не видел, поэтому я бы не стал.

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

Видимо у вас очень-очень старый man:

   If  ping  does  not  receive any reply packets at all it will exit with
       code 1. If a packet count and deadline are both  specified,  and  fewer
       than  count  packets are received by the time the deadline has arrived,
       it will also exit with code 1.  On other error it exits  with  code  2.
       Otherwise  it exits with code 0. This makes it possible to use the exit
       code to see if a host is alive or not. 

2ТС я бы порекомендовал запускать такой ping

ping -l 2 -w 1 -q 8.8.8.8 > /dev/null

(разом отправляется 3 icmp пакета) и смотеть его exit status. Если хоть один ответ был, то $? == 0.

Хотя может лучше не гугл пинговать, а провайдера.

mky ★★★★★
()

Я вот так проверял, работало отлично. В примере изначально был хостнейм и проверка на код 2 работала как надо, для IP оно бесполезно, конечно.


ping 8.8.8.8 -w 10 -c3 -q
res=$?
echo «#> Ping check exit code: $res»
if [ $res == 2 ];then
echo «#> Could not resolve 8.8.8.8»
elif [ $res == 1 ]; then
echo «#> Could not reach 8.8.8.8»
else
echo «#> Restarting net.ppp0»
/etc/init.d/net.ppp0 restart --nocolor &
echo «#> Exit code (/etc/init.d/net.ppp0 restart): $?»
fi

prizident ★★★★★
()
Ответ на: комментарий от mky

Видимо у вас очень-очень старый man:

Да, есть, пропустил.

Хотя может лучше не гугл пинговать, а провайдера.

А что пинговать? DNS? Default gateway? И то и то будет доступно, если баланс на нуле и пров разрешит доступ только ко внутренним ресурсам, а Интернета не будет.

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

А что пинговать? DNS? Default gateway? И то и то будет доступно, если баланс на нуле и пров разрешит доступ только ко внутренним ресурсам, а Интернета не будет.

Ага. Тем более, что и шлюзом, и DNS для моей машины является роутер (который, разумеется, всегда доступен, есть подключение к интернету или нет), который же получает все параметры динамически и узнать их можно только парсингом его веб-интерфейса, что для данной задачи излишество.

KivApple ★★★★★
() автор топика

Nagios наше все

Посмотрите в сторону скриптов от nagios. Там есть прекрасный скрипт check_internet, который все делает. А выполнять команду можно через &&. Скрипты от Nagios можно использовать и без nagios. :-)

ikuchmin
()
Ответ на: комментарий от KivApple

Тем более, что и шлюзом, и DNS для моей машины является роутер

Что абсолютно не мешает пинговать шлюз и DNS провайдера. Но, как я говорил, вряд ли это хорошее решение.

Kroz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.