Reinicie automaticamente, se não houver conexão wifi por um determinado período


13

Parece que meu servidor Raspberry Pi perde a conexão wifi após um tempo aleatório e, de alguma forma, não é capaz de se recuperar automaticamente.

Normalmente, uma reinicialização feita manualmente resolve o problema.

Gostaria de fazê-lo reiniciar automaticamente se não houver wifi após cerca de 30 minutos. Como eu posso fazer isso?


5
Você já tentou desativar a interface e trazê-la de volta? Que tal descarregar e recarregar o módulo do kernel da sua placa wireless? Pode haver outra coisa que você pode fazer para redefinir o cartão sem reiniciar.
— hololeap

1
Sim, isso provavelmente também funcionaria, mas o principal problema aqui é como detectar isso automaticamente e executar a ação apropriada.
— Clamp

Respostas:


10

Esta é essencialmente a resposta de Warwick, apenas com instruções passo a passo.


  1. Crie o seguinte script de shell na sua pasta pessoal:

    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. Altere as permissões para que seja executável

    $ chmod +x check_inet.sh
    
  3. Edite /etc/crontabusando sudoe adicione a seguinte linha (substitua yournamepelo seu nome de usuário real):

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

5

Uma maneira seria colocar uma entrada no cron do root que executa um script a cada 30 minutos. O script testaria a conexão WIFI, talvez usando ping, e gravaria o resultado em um arquivo em / tmp - 1 para a conexão existir, 0 se não existir. As iterações subsequentes do script verificariam esse arquivo e, se fosse 0, e a conexão WIFI ainda estivesse ruim, execute um init 6comando.


3

Acho que a solução hololeap está funcionando.

Minha solução verifica a cada N minutos (dependendo de como você configura seu crontab) em busca de uma conexão de rede em funcionamento. Se a verificação falhar, acompanho a falha. Quando a contagem de falhas é> 5, tento reiniciar o wifi (você também pode reiniciar o Raspberry se a reinicialização do wifi falhar, verifique os comentários).

Aqui está um repositório do GitHub sempre contendo a versão mais recente do script: https://github.com/ltpitt/bash-network-repair-automation

Aqui está, de acordo com a política geral de stackexchange (todas as respostas não devem conter apenas links), também o arquivo network_check.sh, copie e cole-o em qualquer pasta que você desejar, as instruções de instalação estão nos comentários do 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: removi os arquivos temporários para permitir a execução do script na memória e evitar a gravação no cartão SD do Raspberry.


1
Este script evita a reinicialização em desconexões temporárias. Excelente, obrigado!
— wezzix

1
Você parece ter feito uma grande mudança neste script. Pelo que entendi, a versão anterior faria uma passagem, fazendo coisas (incluindo a atualização de arquivos tmp) e saindo. Não contém loops; em vez disso, dependia do cron para executá-lo a cada cinco minutos. Se a rede estivesse inoperante por cinco verificações consecutivas (por um período de cerca de meia hora), o script faria o possível para redefinir a rede. Essa parecia ser uma boa resposta para a pergunta, embora o fato de ela ter sido gravada em arquivos tmp fosse uma desvantagem. ... (continua)
— Scott

(Continua)… A nova versão contém um loop e verifica a rede a cada cinco segundos . Se a rede estiver inativa por cinco verificações consecutivas (ou seja, por um período de cerca de meio minuto ), o script fará o possível para redefinir a rede. (Isso parece ser diferente do que a pergunta pede.) E aqui fica um pouco estranho. Depois de detectar uma falha de rede cinco vezes consecutivas e redefinir a rede, o script é encerrado. (E, aliás, ele sai sem nunca verificar se a rede realmente veio para cima.) ... (Cont)
— Scott

(Continua) ... Mas, enquanto a rede estiver ativa, o script continuará sendo executado para sempre, aguardando a falha da rede. Enquanto isso, o cron continua reiniciando o script a cada cinco minutos. Se a rede permanecer ativa por uma hora, haverá uma dúzia de cópias do script em execução. E, se a rede falhar , essas dúzias de processos se enfrentam, fazendo de forma assíncrona ifdowne ifup, talvez, consertando a rede, e talvez não. ………………………………………………………………………… Se eu entendi algo errado, por favor, explique-me. ... (continua)
— Scott

(Continua) ... (1) Se você pretende fazer uma reformulação tão importante de uma resposta publicada há mais de um ano, deve dizer o que fez. “Eu removi os arquivos temporários para permitir que o script seja executado na memória” não é uma descrição adequada das suas alterações. (2) Parece que você tem uma coleção de pinos quadrados, pinos redondos, orifícios quadrados e orifícios redondos, e não os combinou corretamente. Você deve modificar o script para sair quando perceber que a rede está ativa ou modificá-lo para rodar para sempre e alterar o crontab para iniciar o script apenas uma vez (ou seja, no momento da inicialização).
— Scott Scott

0

I modiffied roteiro de Pitto para o meu MTAC Multitech loraWAN gateway (sem fping). Eu também adicionei um arquivo de log.

#!/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) Por que você ainda fala ifupdownse não os usa? (2) Por que você mudou gateway_ipde uma variável para uma constante codificada?
— Scott

oi scott, esqueci de excluir os comentários ifup ifdown. Esqueci de mudar o gatewy_ip codificado.
— usar o seguinte comando

Agradável! Adicionei uma nova versão que não está usando arquivos temporários (escrever no SD do Raspberry não era uma ótima idéia), você pode conferir na minha resposta.
— Pitto 26/01

Este script herda alguns problemas que estavam na versão original do script de Pitto (que foram corrigidos posteriormente): (1) Se a rede estiver inoperante a partir das 00:00:01 (um segundo após a meia-noite), o script não será reaja até 00:35 (ou seja, 35 minutos depois, na sétima verificação), porque, mesmo que aumente o valor no network_check_tries_filearquivo (quando pingfalhar), não incrementa a network_check_triesvariável. ... (continua)
— Scott

(Continua) ... Portanto, o script é executado sete vezes (às 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 e 00:35) com network_check_triesigual a 0, 1, 2, 3, 4, 5 e 6 - e é apenas na sétima invocação (com network_check_triesigual a 6) que o if [ "$network_check_tries" -gt 5 ]teste é bem-sucedido. Indiscutivelmente, esse é o comportamento correto. Tanto quanto o script sabe, a rede pode ter caído às 00:04:59, portanto, são necessárias sete falhas consecutivas para garantir que você tenha coberto um período de 30 minutos. ... (continua)
— Scott
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.