У меня уже год крутится вот это чудо - пингует яндекс (а при желании пинговать можно что угодно), при потере пинга сначала смотрит есть ли соединение или нет (вдруг "залипло")- если есть -убивает, после чего переподключает. После попытки подключения снова пингует. Если с нескольких попыток не завелось- делает таймаут в три минуты на перекур. Если появилась ошибка "connection limit exceeded" (есть у Ростелекомовского АДСЛ дурная привычка- не подключать, но коннекты накапливать) -ждет 3 минуты на их сброс. И все это логгирует, естественно.
#!/bin/bash
host=yandex.ru
selfname="pinger"
selfpath="/etc/pinger"
logfil="$selfpath/$selfname.log" #сюда бум писать события онлайн/оффлайн
threshold=2 # Порог, выше которого считаем что хост online
statfil="$selfpath/old-state-"$host #Файл, где хранится предыдущее состояние хоста
#подсчитаем количество аналогичных процессов:
ccnt=$( ps ax | grep -v grep | grep -c pinger.sh )
if [ $ccnt -ge 3 ]; then #если процессов и так шибко много, завершаемся
msg="Скрипт уже запущен!"
echo $(date) $msg >>$logfil
exit 0
fi
errors=0
cycles=1
if [ "$1" == "auto" ]; then
msg="Скрипт перезапущен автоматически."
else
msg="Скрипт запущен. Проверяемый хост- $host"
fi
echo $(date) $msg >>$logfil
# Пинговалка. пингует яндекс и возвращает состояние связи в переменную stat
function pinger() {
count=0
for i in {1..5}
do
ping -c1 -w1 $host &>/dev/null
if [ $? -eq 0 ]; then # посчитаем кол-во успешных пингов
count=$(($count + 1))
fi
done
if [ "$count" -ge "$threshold" ]; then
stat=1
tries=0
else
stat=0
fi
}
#функция тупо задает таймаут в 3 минуты для сброса всех подключений и делает запись в лог
function err_exceed() {
killall pppd
echo $(date) "Ошибка - превышено количество попыток подключения(conn limit exceeded). Таймаут 3 минуты" >>$logfil
sleep 180
errors=$(($errors+ 1))
tries=0
}
#функция прекращает попытки подключиться, если нет соединения после определенного количества попыток, и приостанавливает скрипт на 5 минут с записью в лог
function err_noconn() {
killall pppd
echo $(date) "Ошибка - слишком много неудачных попыток подключения. Таймаут 3 минуты " >> $logfil
sleep 180
tries=0
}
function reconn() {
let "conn_count=$(ip link | grep -c ppp) / 2"
if [ $conn_count -eq 0 ]; then
ifup ppp1
sleep 5
else
killall pppd
ifup ppp1
sleep 5
fi
tries=$(($tries+ 1))
}
function checker() {
if [ $tries -ge 5 ]; then
err_noconn
fi
if [ $(tail -100 /var/log/messages | grep -c "limit exceeded") -ge 1 ]; then
err_exceeded
fi
if [ $errors -ge 10 ]; then
echo $(date) "ВИМАНИЕ! Слишком много ошибок, работа скрипта остановлена. Проверьте работу системы, после чего перезапустите скрипт"
sleep 9000000000000
fi
if [ $cycles -ge 720000 ]; then
echo $(date) "Сервисное сообщение -скрипт работает в штатном режиме" >> $logfil
cycles=1
fi
}
pinger
oldstat=$stat
while true
do
pinger
if [ $stat -eq 0 ]; then
if [ "$stat" -ne "$oldstat" ];then
echo $(date) "Связь потеряна" >> $logfil
fi
reconn
fi
if [ $stat -eq 1 ] && [ "$stat" -ne "$oldstat" ]; then
echo $(date) "Связь восстановлена" >> $logfil
fi
oldstat=$stat
cycles=$(($cycles+ 1))
checker
есть еще небольшая приблуда для поддержания его всегда живым, но этот костыль уж каждый лепит на свой вкус.