Reiniciar automáticamente, si no hay conexión wifi por un tiempo determinado

13

Parece que mi servidor Raspberry Pi pierde la conexión wifi después de un tiempo aleatorio y de alguna manera no puede recuperarse automáticamente.

Por lo general, un reinicio hecho a mano resuelve el problema.

Me gustaría hacer que se reinicie automáticamente si no hay wifi después de unos 30 minutos. ¿Cómo puedo hacer eso?

abrazadera
fuente
55
¿Has intentado desactivar la interfaz y volver a activarla? ¿Qué tal descargar y volver a cargar el módulo del kernel para su tarjeta inalámbrica? Puede haber algo más que pueda hacer para restablecer la tarjeta sin reiniciar.
hololeap
1
sí, esto probablemente también funcionaría, pero el problema principal aquí es cómo detectar esto automáticamente y luego realizar la acción adecuada.
abrazadera

Respuestas:

10

Esta es esencialmente la respuesta de Warwick, solo con instrucciones paso a paso.


  1. Cree el siguiente script de shell en su carpeta de inicio:

    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. Cambia los permisos para que sea ejecutable

    $ chmod +x check_inet.sh
    
  3. Edite /etc/crontabusando sudoy agregue la siguiente línea (reemplace yournamecon su nombre de usuario real):

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

Una forma sería poner una entrada en el cron de root que ejecute un script cada 30 minutos. La secuencia de comandos probaría la conexión WIFI, tal vez usando ping, y escribiría el resultado en un archivo en / tmp - 1 si la conexión existe, 0 si no existe. Las iteraciones posteriores del script verificarían ese archivo, y si era 0, y la conexión WIFI seguía siendo mala, ejecute un init 6comando.

Warwick
fuente
3

Creo que la solución hololeap está funcionando.

Mi solución verifica cada N minutos (dependiendo de cómo configure su crontab) para una conexión de red que funcione. Si la verificación falla, hago un seguimiento de la falla. Cuando el recuento de fallas es> 5, intento reiniciar wifi (también puede reiniciar Raspberry si falla el reinicio de wifi, revise los comentarios).

Aquí hay un repositorio de GitHub que siempre contiene la última versión del script: https://github.com/ltpitt/bash-network-repair-automation

Aquí, de acuerdo con la política general de stackexchange (todas las respuestas no solo deben contener enlaces), también el archivo network_check.sh, cópielo y péguelo en la carpeta que desee, las instrucciones de instalación están en los comentarios del 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

editar 26/01/2018: he eliminado los archivos temporales para permitir que el script se ejecute en la memoria y evitar escribir en la tarjeta SD de Raspberry.

Pitto
fuente
1
Este script evita reiniciar en desconexiones temporales. ¡Excelente, gracias!
wezzix
1
Parece que has hecho un cambio importante en este guión. Según lo entendí, la versión anterior haría una pasada, haciendo cosas (incluida la actualización de archivos tmp) y saliendo. No contenía ningún bucle; más bien, dependía de cron para ejecutarlo cada cinco minutos. Si la red estuvo inactiva durante cinco comprobaciones consecutivas (es decir, durante un lapso de aproximadamente media hora), el script haría lo posible para intentar restablecer la red. Esta parecía ser una buena respuesta a la pregunta, aunque el hecho de que escribiera en archivos tmp era un inconveniente. ... (Continúa)
Scott
(Cont.) ... La nueva versión contiene un bucle y verifica la red cada cinco segundos . Si la red está inactiva durante cinco comprobaciones consecutivas (es decir, durante un lapso de aproximadamente medio minuto ), el script hace lo posible para intentar restablecer la red. (Esto parece ser diferente de lo que pide la pregunta). Y aquí se pone un poco raro. Después de detectar una falla de red cinco veces consecutivas y restablecer la red, el script se cierra. (Y, por cierto, sale sin verificar si la red realmente volvió a funcionar). (Cont.)
Scott
(Continúa) ... Pero, mientras la red esté activa, el script sigue ejecutándose para siempre, esperando que la red falle. Mientras tanto, cron sigue reiniciando el script cada cinco minutos. Si la red permanece activa durante una hora, se ejecutará una docena de copias del script. Y, si la red falla , esas docenas de procesos lucharán entre sí, haciendo asincrónicamente ifdowny ifup, tal vez arreglando la red, y tal vez no. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... si he entendido mal algo, explícamelo. ... (Continúa)
Scott
(Continúa) ... (1) Si va a hacer un rediseño tan importante de una respuesta que se ha publicado durante más de un año, debe decir lo que ha hecho. "He eliminado los archivos temporales para permitir que el script se ejecute en la memoria" no es una descripción adecuada de sus cambios. (2) Parece que tiene una colección de clavijas cuadradas, clavijas redondas, orificios cuadrados y orificios redondos, y no los ha combinado correctamente. Debe modificar el script para salir cuando vea que la red está activa, o modificarlo para que se ejecute para siempre, y cambiar el crontab para iniciar el script solo una vez (es decir, en el momento del arranque).
Scott
0

Modifiqué el script de Pitto para mi puerta de enlace multitech mtac loraWAN (sin fping). También agregué un archivo de registro.

#!/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
usuario3036425
fuente
(1) ¿Por qué todavía hablas ifupdownsi no los usas? (2) ¿Por qué cambiaste gateway_ipde una variable a una constante codificada?
Scott
hola Scott, olvidé borrar los comentarios ifup ifdown. Olvidé cambiar el gatewy_ip codificado.
user3036425
¡Agradable! Agregué una nueva versión que no usa archivos temporales (escribir en la SD de Raspberry no fue una gran idea), puede verificarlo en mi respuesta.
Pitto
Este script hereda un par de problemas que estaban en la versión original del script de Pitto (que posteriormente se han corregido): (1) Si la red está inactiva a partir de las 00:00:01 (un segundo después de la medianoche), el script no reaccionar hasta las 00:35 (es decir, 35 minutos más tarde, en la séptima verificación), porque, aunque incrementa el valor en el network_check_tries_filearchivo (cuando pingfalla), no incrementa la network_check_triesvariable. ... (Continúa)
Scott
(Continúa) ... Entonces el guión se ejecuta siete veces (a las 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 y 00:35) con network_check_triesigual a 0, 1, 2, 3, 4, 5 y 6, y es solo en la séptima invocación (con network_check_triesigual a 6) que la if [ "$network_check_tries" -gt 5 ]prueba tiene éxito. Podría decirse que este es el comportamiento correcto. Por lo que sabe el script, la red puede haber caído a las 00:04:59, por lo que se necesitan siete fallas consecutivas para asegurarse de que haya cubierto un período de 30 minutos. ... (Continúa)
Scott