Automatycznie uruchom ponownie, jeśli przez pewien czas nie ma połączenia Wi-Fi


14

Wygląda na to, że mój serwer Raspberry Pi traci połączenie Wi-Fi po przypadkowym czasie i jakoś nie jest w stanie automatycznie odzyskać.

Zwykle ponowne uruchomienie ręczne rozwiązuje problem.

Chciałbym, aby zrestartował się automatycznie, jeśli nie będzie Wi-Fi po około 30 minutach. Jak mogę to zrobić?


5
Czy próbowałeś zdjąć interfejs i przywrócić go z powrotem? Co powiesz na rozładowanie i ponowne załadowanie modułu jądra dla twojej karty bezprzewodowej? Może być coś jeszcze, co możesz zrobić, aby zresetować kartę bez ponownego uruchamiania.
hololeap

1
tak, to prawdopodobnie również zadziałałoby, ale głównym problemem jest to, jak wykryć to automatycznie, a następnie wykonać odpowiednią akcję.
zacisk

Odpowiedzi:


12

To jest w zasadzie odpowiedź Warwicka, tylko instrukcje krok po kroku.


  1. Utwórz następujący skrypt powłoki w folderze domowym:

    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. Zmień uprawnienia, aby można je było wykonać

    $ chmod +x check_inet.sh
    
  3. Edytuj /etc/crontabza pomocą sudoi dodaj następujący wiersz (zastąp yournamerzeczywistą nazwą użytkownika):

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

5

Jednym ze sposobów byłoby umieszczenie wpisu w cronie roota, który uruchamia skrypt co 30 minut. Skrypt przetestuje połączenie WIFI, być może za pomocą ping, i zapisze wynik w pliku w / tmp - 1 dla połączenia istnieje, 0 jeśli nie ma. Kolejne iteracje skryptu sprawdziłyby ten plik, a jeśli byłby 0, a połączenie WIFI było nadal złe, uruchom init 6polecenie.


3

Myślę, że rozwiązanie hololeap działa.

Moje rozwiązanie sprawdza co N minut (w zależności od konfiguracji crontab), czy działa połączenie sieciowe. Jeśli kontrola się nie powiedzie, śledzę awarię. Gdy liczba awarii wynosi> 5, próbuję zrestartować Wi-Fi (możesz także ponownie uruchomić Raspberry, jeśli restart Wi-Fi nie powiedzie się, sprawdź komentarze).

Oto repozytorium GitHub zawsze zawierające najnowszą wersję skryptu: https://github.com/ltpitt/bash-network-repair-automation

Oto, zgodnie z ogólną polityką stackexchange (wszystkie odpowiedzi nie powinny zawierać tylko linków), również plik network_check.sh, skopiuj i wklej go w dowolnym folderze, który lubisz, instrukcje instalacji są w komentarzach skryptu.

#!/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

edytuj 26.01.2018: Usunąłem pliki tymczasowe, aby skrypt mógł działać w pamięci i uniknąć pisania na karcie SD Raspberry.


1
Ten skrypt zapobiega ponownemu uruchomieniu przy tymczasowych rozłączeniach. Wspaniale, dziękuje!
wezzix

1
Wygląda na to, że dokonałeś poważnej zmiany w tym skrypcie. Tak jak to zrozumiałem, poprzednia wersja wykonywała jedno przejście, robiąc różne rzeczy (w tym aktualizując pliki tmp) i kończyła działanie. Nie zawierał żadnych pętli; raczej zależało od crona, aby uruchamiał go co pięć minut. Jeśli sieć nie działała przez pięć kolejnych kontroli (tj. Przez około pół godziny), skrypt zrobiłby wszystko, aby spróbować zresetować sieć. Wydawało się to być dobrą odpowiedzią na to pytanie, chociaż fakt, że napisał do plików tmp, był nieco wadą. … (Ciąg dalszy)
Scott

(Ciąg dalszy)… Nowa wersja zawiera pętlę i sprawdza sieć co pięć sekund . Jeśli sieć nie działa przez pięć kolejnych sprawdzeń (tj. Przez około pół minuty ), skrypt robi rzeczy, aby spróbować zresetować sieć. (Wydaje się, że różni się od tego, o co pyta pytanie). I tutaj robi się trochę dziwnie. Po wykryciu awarii sieci pięć razy z rzędu i zresetowaniu sieci skrypt kończy działanie. (Nawiasem mówiąc, wychodzi z niego bez sprawdzania, czy sieć rzeczywiście wróciła.)… (Ciąg dalszy)
Scott

(Ciąg dalszy)… Ale dopóki sieć jest uruchomiona, skrypt działa nieprzerwanie, czekając na awarię sieci. W międzyczasie cron ponownie uruchamia skrypt co pięć minut. Jeśli sieć będzie działać przez godzinę, uruchomi się kilkanaście kopii skryptu. A jeśli sieć zawiedzie , te tuziny procesów będą ze sobą walczyć, asynchronicznie, ifdowna ifupmoże naprawiając sieć, a może nie. …………………………………………………………………………… Jeśli coś źle zrozumiałem, proszę, wytłumacz mi to. … (Ciąg dalszy)
Scott

(Ciąg dalszy)… (1) Jeśli zamierzasz dokonać tak poważnego przeprojektowania odpowiedzi, która została opublikowana przez ponad rok, powinieneś powiedzieć, co zrobiłeś. „Usunąłem pliki tymczasowe, aby skrypt mógł działać w pamięci” nie jest odpowiednim opisem twoich zmian. (2) Wygląda na to, że masz kolekcję kwadratowych kołków, okrągłych kołków, kwadratowych otworów i okrągłych otworów i nie udało Ci się ich dobrze dopasować. Powinieneś albo zmodyfikować skrypt, aby wyjść, gdy zobaczy, że sieć jest uruchomiona, albo zmodyfikować go, aby działał wiecznie, i zmień crontab, aby uruchamiał skrypt tylko raz (tj. W czasie rozruchu).
Scott

0

Zmodyfikowałem skrypt Pitto dla mojej bramy multitech MTTA LoraWAN (bez fping). Dodałem również plik dziennika.

#!/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) Dlaczego nadal mówisz, ifupdownjeśli go nie używasz? (2) Dlaczego zmieniłeś gateway_ipzmienną na stałą zakodowaną na stałe?
Scott

Cześć Scott, zapomniałem usunąć komentarzy ifup ifdown. Zapomniałem zmienić na stałe gatewy_ip.
user3036425,

Ładny! Dodałem nową wersję, która nie używa plików tymczasowych (pisanie na karcie SD Raspberry nie było świetnym pomysłem), możesz to sprawdzić w mojej odpowiedzi.
Pitto,

Ten skrypt dziedziczy kilka problemów, które były w oryginalnej wersji skryptu Pitto (które zostały następnie poprawione): (1) Jeśli sieć nie działa od 00:00:01 (sekunda po północy), skrypt nie będzie reagować do 00:35 (tj. 35 minut później, przy siódmej kontroli), ponieważ chociaż zwiększa wartość w network_check_tries_filepliku (gdy się pingnie powiedzie), nie zwiększa network_check_trieszmiennej. … (Ciąg dalszy)
Scott

(Ciąg dalszy)… Więc skrypt działa siedem razy (o 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 i 00:35) z wartością network_check_triesrówną 0, 1, 2, 3, 4, 5 i 6 - i tylko przy siódmym wywołaniu ( network_check_triesrównym 6) if [ "$network_check_tries" -gt 5 ]test się powiedzie. Prawdopodobnie jest to prawidłowe zachowanie. O ile skrypt wie, sieć mogła przestać działać o 00:04:59, więc potrzeba siedmiu kolejnych awarii, aby mieć pewność, że obejmiesz okres 30 minut. … (Ciąg dalszy)
Scott
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.