Автоматическая перезагрузка, если в течение определенного времени нет подключения к Wi-Fi


13

Кажется, что мой сервер Raspberry Pi теряет соединение Wi-Fi после случайного времени и не может автоматически восстановиться.

Обычно перезагрузка, выполняемая вручную, решает проблему.

Я бы хотел, чтобы он автоматически перезагружался, если через 30 минут нет Wi-Fi. Как я могу это сделать?


5
Вы пытались отключить интерфейс и вернуть его обратно? Как насчет выгрузки и повторной загрузки модуля ядра для вашей беспроводной карты? Там может быть что-то еще, что вы можете сделать, чтобы сбросить карту без перезагрузки.
— Отпуск

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

Ответы:


10

По сути, это ответ Уорвика с пошаговыми инструкциями.


  1. Создайте следующий скрипт в вашей домашней папке:

    check_inet.sh

    #!/bin/bash
    
    TMP_FILE=/tmp/inet_up
    
    # Edit this function if you want to do something besides reboot
    no_inet_action() {
        shutdown -r +1 'No internet.'
    }
    
    if ping -c5 google.com; then
        echo 1 > $TMP_FILE
    else
        [[ `cat $TMP_FILE` == 0 ]] && no_inet_action || echo 0 > $TMP_FILE
    fi
    
  2. Измените разрешения, чтобы они выполнялись

    $ chmod +x check_inet.sh
    
  3. Отредактируйте, /etc/crontabиспользуя sudoи добавьте следующую строку (замените ее yournameсвоим реальным именем пользователя):

    */30 * * * * /home/yourname/check_inet.sh
    

5

Один из способов - поместить запись в cron root, которая запускает скрипт каждые 30 минут. Скрипт будет проверять соединение WIFI, возможно, используя ping, и записывать результат в файл в / tmp - 1, если соединение существует, 0, если нет. Последующие итерации скрипта затем проверили бы этот файл, и если он был равен 0, а соединение WIFI все еще было плохим, запустите init 6команду.


3

Я думаю, что решение hololeap работает.

Мое решение проверяет каждые N минут (в зависимости от того, как вы настраиваете свой crontab) для работающего сетевого соединения. Если проверка не удалась, я отслеживаю неудачу. Когда количество ошибок> 5, я пытаюсь перезапустить Wi-Fi (вы также можете перезагрузить Raspberry, если перезапуск Wi-Fi не удается, проверьте комментарии).

Вот репозиторий GitHub, всегда содержащий последнюю версию скрипта: https://github.com/ltpitt/bash-network-repair-automation

Вот, в соответствии с общей политикой stackexchange (все ответы должны содержать не только ссылки), а также файл network_check.sh, скопируйте и вставьте его в любую понравившуюся папку, инструкции по установке находятся в комментариях скрипта.

#!/bin/bash
# Author:
# twitter.com/pitto
#
# HOW TO INSTALL:
#
# 1) Install ifupdown and fping with the following command:
# sudo apt-get install ifupdown fping
#
# 2) Then install this script into a folder and add to your crontab -e this row:
# */5 * * * * /yourhome/yourname/network_check.sh
#
# Note:
# If you want to perform automatic repair fsck at reboot
# remember to uncomment fsck autorepair here: nano /etc/default/rcS

# Let's clear the screen
clear

# Write here the gateway you want to check to declare network working or not
gateway_ip='www.google.com'

# Here we initialize the check counter to zero
network_check_tries=0

# Here we specify the maximum number of failed checks
network_check_threshold=5

# This function will be called when network_check_tries is equal or greather than network_check_threshold
function restart_wlan0 {
    # If network test failed more than $network_check_threshold
    echo "Network was not working for the previous $network_check_tries checks."
    # We restart wlan0
    echo "Restarting wlan0"
    /sbin/ifdown 'wlan0'
    sleep 5
    /sbin/ifup --force 'wlan0'
    sleep 60
    # If network is still down after recovery and you want to force a reboot simply uncomment following 4 rows
    #host_status=$(fping $gateway_ip)
    #if [[ $host_status != *"alive"* ]]; then
    #    reboot
    #fi
}

# This loop will run network_check_tries times and if we have network_check_threshold failures
# we declare network as not working and we restart wlan0
while [ $network_check_tries -lt $network_check_threshold ]; do
    # We check if ping to gateway is working and perform the ok / ko actions
    host_status=$(fping $gateway_ip)
    # Increase network_check_tries by 1 unit
    network_check_tries=$[$network_check_tries+1]
    # If network is working
    if [[ $host_status == *"alive"* ]]; then
        # We print positive feedback and quit
        echo "Network is working correctly" && exit 0
    else
        # If network is down print negative feedback and continue
        echo "Network is down, failed check number $network_check_tries of $network_check_threshold"
    fi
    # If we hit the threshold we restart wlan0
    if [ $network_check_tries -ge $network_check_threshold ]; then
        restart_wlan0
    fi
    # Let's wait a bit between every check
    sleep 5 # Increase this value if you prefer longer time delta between checks
done

править 26.01.2008: я удалил временные файлы, чтобы скрипт работал в памяти и не записывал на SD-карту Raspberry.


1
Этот сценарий позволяет избежать перезапуска при временных отключениях. Отлично, спасибо!
— wezzix

1
Вы, кажется, внесли серьезные изменения в этот скрипт. Как я понял, предыдущая версия делала один проход, выполняла какие-то действия (включая обновление файлов tmp) и выходила. Там не было никаких петель; скорее, от cron зависеть запускать его каждые пять минут. Если сеть была отключена в течение пяти последовательных проверок (т.е. в течение примерно получаса), сценарий попытался бы выполнить сброс сети. Это казалось хорошим ответом на вопрос, хотя тот факт, что он записывал в файлы tmp, был небольшим недостатком. … (Продолжение)
— Скотт

(Продолжение)… Новая версия содержит цикл и проверяет сеть каждые пять секунд . Если сеть не работает в течение пяти последовательных проверок (т. Е. В течение примерно полминуты ), сценарий пытается выполнить сброс сети. (Похоже, это отличается от того, что задает вопрос.) И здесь это становится немного странным. После того, как он обнаруживает сбой сети пять раз подряд и сбрасывает сеть, сценарий завершается. (И, между прочим, он выходит, даже не проверяя, действительно ли сеть восстановилась.)… (Продолжение)
— Скотт

(Продолжение)… Но пока сеть работает, сценарий работает вечно, ожидая сбоя сети. Тем временем, cron продолжает перезапускать скрипт каждые пять минут. Если сеть будет работать в течение часа, будет запущено несколько десятков копий скрипта. И, если в сети произойдет сбой , эти дюжины процессов будут сражаться друг с другом, асинхронно ifdownи ifup, возможно, исправляя сеть, а может и нет. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... Если я что-то не так понял, объясните мне … (Продолжение)
— Скотт

(Продолжение)… (1) Если вы собираетесь сделать такой значительный редизайн ответа, который был опубликован более года, вам следует сказать, что вы сделали. «Я удалил временные файлы, чтобы скрипт работал в памяти» - это не адекватное описание ваших изменений. (2) Кажется, что у вас есть коллекция квадратных колышков, круглых колышков, квадратных и круглых отверстий, и вы не правильно их подобрали. Вам следует либо изменить скрипт для выхода, когда он увидит, что сеть работает, либо изменить его так, чтобы он работал вечно, и изменить crontab для запуска скрипта только один раз (т. Е. Во время загрузки).
— Скотт

0

Я изменил сценарий Pitto для моего многоцелевого шлюза mtac loraWAN (без fping). Я также добавил файл журнала.

#!/bin/bash
# Author: 
# twitter.com/pitto
#
# HOW TO INSTALL:
#
# 1) Install ifupdown with the following command:
# sudo apt-get install ifupdown
#
# 2) Create files in any folder you like (ensure that the filename variables, set below,
# match the names of the files you created) with the following commands:
# sudo touch /home/root/scripts/network_check_tries.txt &&
#                               sudo chmod 777 /home/root/network_check_tries.txt
# sudo touch /home/root/scripts/N_reboots_file.txt      &&
#                               sudo chmod 777 /home/root/N_reboots_file.txt
# sudo touch /home/root/scripts/network_check.log       &&
#                               sudo chmod 777 /home/root/network_check.log
#
# 3) Then install this script into a folder and add to your crontab -e this row:
# */5 * * * * /yourhome/yourname/network_check.sh
#
# Note:
# If additionally you want to perform automatic repair fsck at reboot
# remember to uncomment fsck autorepair here: nano /etc/default/rcS

# Specify the paths of the text file where the network failures count, reboot count,
# and log will be held:
network_check_tries_file='/home/root/network_check_tries.txt'
N_reboots_file='/home/root/N_reboots_file.txt'
log_file='/home/root/network_check.log'

# Save file contents into corresponding variables:
network_check_tries=$(cat "$network_check_tries_file")
N_reboots=$(cat "$N_reboots_file")


# If host is / is not alive we perform the ok / ko actions that simply involve
# increasing or resetting the failure counter
ping -c1 google.com
if [ $? -eq 0 ]
then
    # if you want to log when there is no problem also,
    # uncomment the following line, starting at "date".
    echo 0 > "$network_check_tries_file" #&& date >> "$log_file" && echo -e "-- Network is working correctly -- \n" >> "$log_file"
else
    date >> "$log_file" && echo -e "-- Network is down... -- \n" >> "$log_file" && echo "$(($network_check_tries + 1))" > "$network_check_tries_file"
fi

# If network test failed more than 5 times (you can change this value to whatever you
# prefer)
if [ "$network_check_tries" -gt 5 ] 
then
    # Time to restart ppp0
    date >> "$log_file" && echo "Network was not working for the previous $network_check_tries checks." >> "$log_file" && echo "Restarting ppp0" >> "$log_file"
    killall pppd
    sleep 20
    /usr/sbin/pppd call gsm
    sleep 120
    # Then we check again if restarting wlan0 fixed the issue;
    # if not we reboot as last resort
    ping -c1 google.com
    if [ $? -eq 0 ]
    then
        date >> "$log_file" && echo -e "-- Network is working correctly -- \n" >> "$log_file" && echo 0 > "$network_check_tries_file"
    else
        date >> "$log_file" && echo -e  "-- Network still down after ifdownup... reboot time!-- \n" >> "$log_file" && echo 0 > "$network_check_tries_file" && echo "$(($N_reboots + 1))" > "$N_reboots_file" && reboot
    fi
fi

(1) Почему вы все еще говорите, ifupdownесли не используете его / их? (2) Почему вы перешли gateway_ipс переменной на жестко закодированную константу?
— Скотт

привет Скотт, я забыл удалить комментарии ifup ifdown. Я забыл изменить жестко запрограммированный gatewy_ip.
— user3036425

Ницца! Я добавил новую версию, которая не использует временные файлы (запись на SD-диске Raspberry не была такой хорошей идеей), вы можете проверить это в моем ответе.
— Питто

Этот сценарий наследует пару проблем, которые были в исходной версии сценария Питто (которые впоследствии были исправлены): (1) Если сеть не работает, начиная с 00:00:01 (одна секунда после полуночи), сценарий не будет реагировать до 00:35 (т. е. 35 минут спустя, на седьмой проверке), потому что, даже если он увеличивает значение в network_check_tries_fileфайле (когда происходит pingсбой), он не увеличивает значение network_check_triesпеременной. … (Продолжение)
— Скотт

(Продолжение)… Таким образом, сценарий выполняется семь раз (в 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 и 00:35) с network_check_triesравным 0, 1, 2, 3, 4, 5 и 6 - и только на седьмом вызове (с network_check_triesравным 6) if [ "$network_check_tries" -gt 5 ]тест проходит успешно. Возможно, это правильное поведение. Насколько известно сценарию, в 00:04:59 сеть, возможно, отключилась, поэтому требуется семь последовательных сбоев, чтобы убедиться, что вы преодолели 30-минутный период. … (Продолжение)
— Скотт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.