Redémarrez automatiquement, si aucune connexion wifi pendant un certain temps

13

Il semble que mon serveur Raspberry Pi perd la connexion wifi après un temps aléatoire et ne soit pas en mesure de récupérer automatiquement.

Habituellement, un redémarrage fait à la main résout le problème.

Je voudrais le redémarrer automatiquement s'il n'y a pas de wifi après environ 30 minutes. Comment puis je faire ça?

serrer
la source
5
Avez-vous essayé de supprimer l'interface et de la réactiver? Que diriez-vous de décharger et de recharger le module du noyau pour votre carte sans fil? Vous pouvez peut-être faire autre chose pour réinitialiser la carte sans redémarrer.
hololeap
1
oui, cela fonctionnerait probablement aussi, mais le principal problème ici est de savoir comment le détecter automatiquement, puis effectuer l'action appropriée.
pince

Réponses:

10

C'est essentiellement la réponse de Warwick, juste avec des instructions étape par étape.


  1. Créez le script shell suivant dans votre dossier personnel:

    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. Modifiez les autorisations afin qu'il soit exécutable

    $ chmod +x check_inet.sh
    
  3. Modifiez en /etc/crontabutilisant sudoet ajoutez la ligne suivante (remplacez yournamepar votre nom d'utilisateur réel):

    */30 * * * * /home/yourname/check_inet.sh
    
hololeap
la source
5

Une façon serait de mettre une entrée dans le cron de root qui exécute un script toutes les 30 minutes. Le script testerait la connexion WIFI, peut-être en utilisant ping, et écrirait le résultat dans un fichier dans / tmp - 1 pour la connexion existe, 0 si ce n'est pas le cas. Les itérations suivantes du script vérifieraient alors ce fichier, et si c'était 0 et que la connexion WIFI était toujours mauvaise, exécutez une init 6commande.

Warwick
la source
3

Je pense que la solution hololeap fonctionne.

Ma solution vérifie toutes les N minutes (selon la façon dont vous configurez votre crontab) pour une connexion réseau fonctionnelle. Si la vérification échoue, je garde la trace de l'échec. Lorsque le nombre d'échecs est> 5, j'essaie de redémarrer le wifi (vous pouvez également redémarrer Raspberry si le redémarrage du wifi échoue, consultez les commentaires).

Voici un dépôt GitHub contenant toujours la dernière version du script: https://github.com/ltpitt/bash-network-repair-automation

Voici, selon la politique générale de stackexchange (toutes les réponses ne doivent pas seulement contenir des liens), également le fichier network_check.sh, copiez-le et collez-le dans n'importe quel dossier que vous aimez, les instructions d'installation sont dans les commentaires du script.

#!/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 26/01/2018: J'ai supprimé les fichiers temporaires afin de laisser le script s'exécuter en mémoire et éviter d'écrire sur la carte SD de Raspberry.

Pitto
la source
1
Ce script évite le redémarrage sur les déconnexions temporaires. Excellent, merci!
wezzix
1
Vous semblez avoir fait un changement majeur dans ce script. Si je comprends bien, la version précédente ferait un passage, faire des choses (y compris la mise à jour des fichiers tmp) et quitter. Il ne contenait aucune boucle; il dépendait plutôt de cron pour l'exécuter toutes les cinq minutes. Si le réseau était en panne pendant cinq vérifications consécutives (c'est-à-dire pendant une durée d'environ une demi-heure), le script ferait des choses pour essayer de réinitialiser le réseau. Cela semblait être une bonne réponse à la question, bien que le fait qu'il ait écrit dans des fichiers tmp était un peu un inconvénient. … (Suite)
Scott
(Suite)… La nouvelle version contient une boucle et vérifie le réseau toutes les cinq secondes . Si le réseau est en panne pendant cinq vérifications consécutives (c'est-à-dire pendant environ une demi-minute ), le script fait des choses pour essayer de réinitialiser le réseau. (Cela semble être différent de ce que la question demande.) Et ici, cela devient un peu bizarre. Après avoir détecté une panne de réseau cinq fois de suite et réinitialisé le réseau, le script se ferme. (Et, incidemment, il se ferme sans jamais vérifier si le réseau est réellement revenu.)… (Suite)
Scott
(Suite)… Mais, tant que le réseau est actif, le script continue de s'exécuter indéfiniment, en attendant l'échec du réseau. Pendant ce temps, cron continue de redémarrer le script toutes les cinq minutes. Si le réseau reste actif pendant une heure, il y aura une douzaine de copies du script en cours d'exécution. Et, si le réseau tombe en panne alors, ces douzaines de processus se battront les uns contre les autres, le faisant de manière asynchrone ifdownet ifup, peut-être réparant le réseau, et peut-être pas. ………………………………………………………………………………… Si j'ai mal compris quelque chose, veuillez me l'expliquer. … (Suite)
Scott
(Suite)… (1) Si vous envisagez une refonte majeure d'une réponse publiée depuis plus d'un an, vous devez dire ce que vous avez fait. «J'ai supprimé les fichiers temporaires afin de laisser le script s'exécuter en mémoire» n'est pas une description adéquate de vos modifications. (2) Il semble que vous ayez une collection de chevilles carrées, de chevilles rondes, de trous carrés et de trous ronds, et que vous ne les avez pas correctement assortis. Vous devez soit modifier le script pour quitter lorsqu'il voit que le réseau est en place, soit le modifier pour qu'il s'exécute indéfiniment, et modifier la crontab pour démarrer le script une seule fois (c'est-à-dire au démarrage).
Scott
0

J'ai modifié le script de Pitto pour ma passerelle multitech mtac loraWAN (pas de fping). J'ai également ajouté un fichier journal.

#!/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
la source
(1) Pourquoi parlez-vous toujours ifupdownsi vous ne les utilisez pas? (2) Pourquoi êtes-vous passé gateway_ipd'une variable à une constante codée en dur?
Scott
salut scott, j'ai oublié de supprimer les commentaires ifup ifdown. J'ai oublié de changer le gatewy_ip codé en dur.
user3036425
Agréable! J'ai ajouté une nouvelle version qui n'utilise pas de fichiers temporaires (écrire sur la SD de Raspberry n'était pas une si bonne idée), vous pouvez le vérifier dans ma réponse.
Pitto
Ce script hérite de quelques problèmes qui se trouvaient dans la version originale du script de Pitto (qui ont ensuite été corrigés): (1) Si le réseau est en panne à partir de 00:00:01 (une seconde après minuit), le script ne réagir jusqu'à 00:35 (c'est-à-dire 35 minutes plus tard, lors du septième contrôle), car, même s'il incrémente la valeur du network_check_tries_filefichier (en cas d' pingéchec), il n'incrémente pas la network_check_triesvariable. … (Suite)
Scott
(Suite)… Le script s'exécute donc sept fois (à 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 et 00:35) avec une valeur network_check_trieségale à 0, 1, 2, 3, 4, 5 et 6 - et ce n'est qu'à la septième invocation (avec une valeur network_check_trieségale à 6) que le if [ "$network_check_tries" -gt 5 ]test réussit. Sans doute, c'est le bon comportement. Pour autant que le script le sache, le réseau peut avoir baissé à 00:04:59, il faut donc sept échecs consécutifs pour être sûr d'avoir couvert une période de 30 minutes. … (Suite)
Scott