Автоматическая перезагрузка, если в течение определенного времени нет подключения к 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
    
hololeap
источник
5

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

Warwick
источник
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.

Pitto
источник
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
user3036425
источник
(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-минутный период. … (Продолжение)
Скотт