Automatisch neu starten, wenn für eine bestimmte Zeit keine WLAN-Verbindung besteht

13

Es scheint, dass mein Raspberry Pi-Server nach einer zufälligen Zeit die WLAN-Verbindung verliert und irgendwie nicht automatisch wiederhergestellt werden kann.

In der Regel wird das Problem durch einen Neustart von Hand behoben.

Ich möchte einen automatischen Neustart durchführen, wenn nach ca. 30 Minuten kein WLAN verfügbar ist. Wie kann ich das machen?

Klemme
quelle
5
Haben Sie versucht, die Schnittstelle herunterzufahren und wieder hochzufahren? Wie wäre es mit dem Entladen und erneuten Laden des Kernelmoduls für Ihre WLAN-Karte? Möglicherweise können Sie noch etwas tun, um die Karte zurückzusetzen, ohne einen Neustart durchzuführen.
Hololeap
1
Ja, das würde wahrscheinlich auch funktionieren, aber das Hauptproblem hier ist, wie man dies automatisch erkennt und dann die entsprechende Aktion ausführt.
Klemme

Antworten:

10

Dies ist im Wesentlichen Warwicks Antwort, nur mit schrittweisen Anweisungen.


  1. Erstellen Sie das folgende Shell-Skript in Ihrem Basisordner:

    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. Ändern Sie die Berechtigungen so, dass sie ausführbar sind

    $ chmod +x check_inet.sh
    
  3. Bearbeiten Sie /etc/crontabmit sudound fügen Sie die folgende Zeile hinzu (ersetzen Sie sie yournamedurch Ihren tatsächlichen Benutzernamen):

    */30 * * * * /home/yourname/check_inet.sh
    
hololeap
quelle
5

Eine Möglichkeit wäre, einen Eintrag in den Cron von root zu schreiben, der alle 30 Minuten ein Skript ausführt. Das Skript testet die WIFI-Verbindung, verwendet möglicherweise ping, und schreibt das Ergebnis in eine Datei in / tmp-1, damit eine Verbindung besteht, andernfalls 0. Nachfolgende Iterationen des Skripts überprüften dann diese Datei. Wenn sie 0 war und die WIFI-Verbindung immer noch schlecht war, führen Sie einen init 6Befehl aus.

Warwick
quelle
3

Ich denke, Hololeap-Lösung funktioniert.

Meine Lösung überprüft alle N Minuten (abhängig davon, wie Sie Ihre crontab konfigurieren), ob eine Netzwerkverbindung besteht. Wenn die Prüfung fehlschlägt, verfolge ich den Fehler. Wenn die Fehleranzahl> 5 ist, versuche ich, WLAN neu zu starten (Sie können Raspberry auch neu starten, wenn der WLAN-Neustart fehlschlägt, überprüfen Sie die Kommentare).

Hier ist ein GitHub-Repo, das immer die neueste Version des Skripts enthält: https://github.com/ltpitt/bash-network-repair-automation

Nach den allgemeinen Richtlinien von stackexchange (alle Antworten sollten nicht nur Links enthalten) können Sie auch die Datei network_check.sh kopieren und in einen beliebigen Ordner einfügen. Die Installationsanweisungen finden Sie in den Kommentaren des Skripts.

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

edit 1/26/2018: Ich habe die temporären Dateien entfernt, um das Skript im Speicher laufen zu lassen und das Schreiben auf die SD-Karte von Raspberry zu vermeiden.

Pitto
quelle
1
Dieses Skript vermeidet einen Neustart bei vorübergehenden Verbindungsabbrüchen. Großartig, danke!
Wezzix
1
Sie haben anscheinend eine wesentliche Änderung in diesem Skript vorgenommen. So wie ich es verstanden habe, hat die vorherige Version einen Durchgang hinter sich gebracht, Dinge erledigt (einschließlich der Aktualisierung von tmp-Dateien) und das Programm beendet. Es enthielt keine Schleifen; Vielmehr hing es von cron ab, dass es alle fünf Minuten ausgeführt wurde. Wenn das Netzwerk für fünf aufeinanderfolgende Überprüfungen (dh für eine Zeitspanne von etwa einer halben Stunde) ausgefallen wäre, würde das Skript versuchen, das Netzwerk zurückzusetzen. Dies schien eine gute Antwort auf die Frage zu sein, obwohl die Tatsache, dass es in tmp-Dateien geschrieben wurde, ein kleiner Nachteil war. … (Fortsetzung)
Scott
(Fortsetzung)… Die neue Version enthält eine Schleife und überprüft das Netzwerk alle fünf Sekunden . Wenn das Netzwerk für fünf aufeinanderfolgende Überprüfungen außer Betrieb ist (dh für eine Zeitspanne von etwa einer halben Minute ), unternimmt das Skript einige Schritte, um das Netzwerk zurückzusetzen. (Dies scheint anders zu sein, als in der Frage gefordert.) Und hier wird es etwas seltsam. Nachdem ein fünfmaliger Netzwerkfehler festgestellt und das Netzwerk zurückgesetzt wurde, wird das Skript beendet. (Und im Übrigen wird es beendet, ohne jemals zu überprüfen, ob das Netzwerk tatsächlich wieder verfügbar ist.)… (Fortsetzung)
Scott
(Fortsetzung) ... Solange das Netzwerk aktiv ist, wird das Skript für immer ausgeführt und wartet darauf, dass das Netzwerk ausfällt. In der Zwischenzeit startet cron das Skript alle fünf Minuten neu. Wenn das Netzwerk eine Stunde lang aktiv ist, werden ein Dutzend Kopien des Skripts ausgeführt. Und wenn das Netzwerk ausfällt , kämpfen diese Dutzend Prozesse miteinander, indem sie das Netzwerk asynchron ausführen ifdownund ifupmöglicherweise reparieren und möglicherweise auch nicht. ………………………………………………………………………………… falls ich etwas falsch verstanden habe, erkläre es mir bitte. … (Fortsetzung)
Scott
(Fortsetzung)… (1) Wenn Sie eine Antwort, die seit über einem Jahr veröffentlicht wurde, so umfassend überarbeiten möchten, sollten Sie angeben, was Sie getan haben. "Ich habe die temporären Dateien entfernt, damit das Skript im Speicher ausgeführt werden kann" ist keine angemessene Beschreibung Ihrer Änderungen. (2) Anscheinend haben Sie eine Sammlung von quadratischen Stiften, runden Stiften, quadratischen Löchern und runden Löchern, und Sie haben sie nicht richtig aufeinander abgestimmt. Sie sollten entweder das Skript so ändern, dass es beendet wird, wenn das Netzwerk aktiv ist, oder es so ändern, dass es für immer ausgeführt wird, und die crontab so ändern, dass das Skript nur einmal (dh beim Start) gestartet wird.
Scott
0

Ich habe Pittos Skript für mein Multitech-MTAC-Lorawan-Gateway modifiziert (kein Fping). Ich habe auch eine Protokolldatei hinzugefügt.

#!/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
quelle
(1) Warum redest du immer noch darüber, ifupdownwenn du es / sie nicht benutzt? (2) Warum haben Sie gateway_ipvon einer Variablen zu einer fest codierten Konstante gewechselt?
Scott
hi scott, ich habe vergessen die ifup ifdown Kommentare zu löschen. Ich habe vergessen, das fest codierte gatewy_ip zu ändern.
user3036425
Nett! Ich habe eine neue Version hinzugefügt, die keine temporären Dateien verwendet (das Schreiben auf Raspberrys SD war keine so großartige Idee). Sie können dies in meiner Antwort überprüfen.
Pitto
Dieses Skript erbt einige Probleme, die in der Originalversion von Pittos Skript aufgetreten sind (die anschließend behoben wurden): (1) Wenn das Netzwerk ab 00:00:01 Uhr (eine Sekunde nach Mitternacht) ausgefallen ist, wird das Skript nicht ausgeführt reagieren Sie bis 00:35 (dh 35 Minuten später, bei der siebten Prüfung), da die Variable nicht inkrementiert wird , obwohl der Wert in der network_check_tries_fileDatei erhöht wird (wenn dies pingfehlschlägt) network_check_tries. … (Fortsetzung)
Scott
(Fortsetzung)… Das Skript wird also sieben Mal ausgeführt (um 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 und 00:35) mit den network_check_triesWerten 0, 1, 2, 3, 4, 5 und 6 - und erst beim siebten Aufruf (mit network_check_triesgleich 6) ist der if [ "$network_check_tries" -gt 5 ]Test erfolgreich. Das ist wohl das richtige Verhalten. Nach Kenntnis des Skripts ist das Netzwerk möglicherweise um 00:04:59 Uhr ausgefallen. Sieben aufeinanderfolgende Fehler sind daher erforderlich, um sicherzustellen, dass Sie einen Zeitraum von 30 Minuten abgedeckt haben. … (Fortsetzung)
Scott