Автоматично перезавантажте, якщо протягом певного часу немає з'єднання Wi-Fi


14

Схоже, мій сервер Raspberry Pi втрачає з'єднання через Wi-Fi через випадковий час і якимось чином не може відновитись автоматично.

Зазвичай проблема перезавантаження, зроблена вручну, вирішує проблему.

Я хотів би зробити його перезавантаження автоматично, якщо через 30 хвилин немає Wi-Fi. Як я можу це зробити?


5
Ви намагалися зняти інтерфейс і повернути його назад? Як щодо вивантаження та повторного завантаження модуля ядра для вашої бездротової картки? Ви можете зробити щось інше, щоб скинути картку без перезавантаження.
hololeap

1
так, це, ймовірно, також спрацює, але головне питання тут - як це автоматично виявити, а потім виконати відповідні дії.
затискач

Відповіді:


12

Це по суті відповідь Уоріка, лише покрокові інструкції.


  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

Я думаю, що рішення хололіпа працює.

Моє рішення перевіряє кожні N хвилин (залежно від того, як ви налаштуєте свій crontab) на робоче мережеве з'єднання. Якщо чек не вдається, я відслідковую помилку. Коли кількість помилок становить> 5, я намагаюся перезапустити wifi (ви також можете перезапустити 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.2018: Я видалив тимчасові файли, щоб сценарій запускався в пам'яті і уникав запису на SD-карту Raspberry.


1
Цей скрипт дозволяє уникнути перезавантаження при тимчасових відключеннях. Відмінно, дякую!
wezzix

1
Здається, ви внесли серйозні зміни в цей сценарій. Як я зрозумів, попередня версія зробить один прохід, виконуючи роботи (включаючи оновлення tmp-файлів) та завершивши роботу. Він не містив циклів; швидше, це залежало від крона, щоб запускати його кожні п’ять хвилин. Якщо мережа була відключена протягом п'яти послідовних перевірок (тобто протягом проміжку приблизно півгодини), сценарій зробив би спробу відновити мережу. Це здавалося гарною відповіддю на питання, хоча той факт, що він писав у файли tmp, був трохи недоліком. … (Продовження)
Скотт

(Продовження)… Нова версія містить цикл і перевіряє мережу кожні п’ять секунд . Якщо мережа не працює протягом п’яти послідовних перевірок (тобто протягом проміжку приблизно півхвилини ), сценарій робить все, щоб спробувати скинути мережу. (Це, здається, відрізняється від того, про що задається питання.) І тут це стає трохи дивно. Після того, як він виявить п'ять разів поспіль мережевий збій і скидає мережу, сценарій залишається. (І, до речі, він виходить, не перевіряючи, чи мережа насправді відновилася.)… (Продовження)
Скотт,

(Продовження)… Але, поки мережа працює, сценарій постійно працює , чекаючи, коли мережа вийде з ладу. Тим часом, cron продовжує перезапускати сценарій кожні п’ять хвилин. Якщо мережа залишається протягом години, буде запущено десяток примірників сценарію. І якщо мережа вийде з ладу , ці десятки процесів будуть битися між собою, асинхронно робити ifdownі ifup, можливо, фіксуючи мережу, а може й ні. ……………………………………………………………………………… Якщо я щось неправильно зрозумів, будь ласка, поясніть мені це. … (Продовження)
Скотт

(Продовження)… (1) Якщо ви збираєтеся зробити такий великий дизайн відповіді, який розміщувався протягом року, вам слід сказати, що ви зробили. "Я видалив тимчасові файли для того, щоб сценарій запускався в пам'яті" не є адекватним описом ваших змін. (2) Схоже, у вас є колекція квадратних кілочків, круглих кілочків, квадратних отворів і круглих отворів, і ви їх не зібрали правильно. Вам слід або змінити сценарій для виходу, коли він побачить, що мережа працює, або змінити її для запуску назавжди, і змінити crontab, щоб запустити сценарій лише один раз (тобто під час завантаження).
Скотт

0

Я модифікував сценарій Пітто для свого багатоповерхового 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.
користувач3036425

Приємно! Я додав нову версію, яка не використовує тимчасові файли (писати на 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.