草庐IT

openwrt 断网重启检测脚本

darren blog 2023-03-28 原文

背景

openwrt 有些固件不太稳定,会时不时的断网,导致家里无法上网,遇到这种情况只能手动重启openwrt设备,该操作不方便,作为一个极客爱好者,那肯定是要实现自动化处理的了,写一个简单的脚本加入到crontab定时任务中,就可完全自动化检测了,解放双手。

脚本思路

1、ping指定域名5次,只要要有2次以上的包响应,才表示网络畅通
2、如果低于2次,则视为网络不通,重启网络,并等待20秒
3、再次检测网络如果还是网络不通的话,则重启openwrt服务
4、当连续失败计数大道10次以上,则重启次数改为10分钟,重复上述步骤,当网络畅通后,计数归零

脚本

#!/bin/bash

# 日志默认目录
Log_DIR="/data/shell/log"
# 连续计数
NETWORK_CHECK_COUNTER_FILE="${Log_DIR}/network-check-counter.log"
# 执行日志
NETWORK_CHECK_LOG_FILE="${Log_DIR}/network-check.log"
# 默认计数为0
COUNTER=0

# 连续失败计数大于该数值,则进行 RESTART_INTERVAL 秒等待,再执行重新检测
COUNTER_THRESHOLD=10
# 持续失败,后默认等待时间(秒),然后再重启
RESTART_INTERVAL=600

# 检查目录是否存在,不存在则创建
if [ ! -d "$Log_DIR" ]; then
    echo "Creating directory $Log_DIR"
    mkdir -p "$Log_DIR"
fi

# 检查文件是否存在,如果不存在则创建文件
touch $NETWORK_CHECK_LOG_FILE

if [ ! -e $NETWORK_CHECK_COUNTER_FILE ]; then
    touch $NETWORK_CHECK_COUNTER_FILE
    echo "0" >$NETWORK_CHECK_COUNTER_FILE
fi
COUNTER=$(cat $NETWORK_CHECK_COUNTER_FILE)

# 检测网络是否畅通
function ping_domain() {
    # ping的域名或者DNS
    local domain=114.114.114.114
    # ping的次数
    local tries=6
    # 请求成功次数
    local packets_responded=0

    for i in $(seq 1 $tries); do
        if ping -c 1 $domain >/dev/null; then
            ((packets_responded++))
            sleep 1
        fi
    done

    # 如果请求成功总次数大于2,则表示成功
    if [ $packets_responded -ge 2 ]; then
        echo "true"
    else
        echo "false"
    fi
}

# 检测网络连接函数
function check_network() {
    # 如果ping 6次至少有2次包未响应,则执行一下代码
    if [ $(ping_domain) = "false" ]; then
        # 如果N无法连接网络,则重启网络
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接失败"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接失败" >>$NETWORK_CHECK_LOG_FILE
        /etc/init.d/network restart
        sleep 20
        if [ $(ping_domain) = "false" ]; then
            # 如果仍无法连接网络,则重启WLAN服务
            echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接仍然失败,重启WLAN服务"
            echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接仍然失败,重启WLAN服务" >>$NETWORK_CHECK_LOG_FILE

            /sbin/ifup wan
            echo "$(date '+%Y-%m-%d %H:%M:%S') Wlan服务已重启"
            echo "$(date '+%Y-%m-%d %H:%M:%S') Wlan服务已重启" >>$NETWORK_CHECK_LOG_FILE
            echo $(($(cat $NETWORK_CHECK_COUNTER_FILE) + 1)) >$NETWORK_CHECK_COUNTER_FILE
            sleep 30

            if [ $(ping_domain) = "false" ]; then
                echo "$(date '+%Y-%m-%d %H:%M:%S') 重启WLAN后,联网失败,准备重启服务器"
                echo "$(date '+%Y-%m-%d %H:%M:%S') 重启WLAN后,联网失败,准备重启服务器" >>$NETWORK_CHECK_LOG_FILE
                echo $(($(cat $NETWORK_CHECK_COUNTER_FILE) + 1)) >$NETWORK_CHECK_COUNTER_FILE
                /sbin/reboot
            else
                echo "$(date '+%Y-%m-%d %H:%M:%S') 重启WLAN后,连接已恢复"
                echo "$(date '+%Y-%m-%d %H:%M:%S') 重启WLAN后,连接已恢复" >>$NETWORK_CHECK_LOG_FILE
                echo "0" >$NETWORK_CHECK_COUNTER_FILE
            fi
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启网络网络后,连接已恢复"
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启网络网络后,连接已恢复" >>$NETWORK_CHECK_LOG_FILE
            echo "0" >$NETWORK_CHECK_COUNTER_FILE
        fi
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接正常"
        # 可以通过server 酱发送消息
        #if [ $(cat $NETWORK_CHECK_COUNTER_FILE) -ge 1 ]; then
        # 如果网络畅通且之前有失败计数,则进行POST请求
        #echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接已恢复,发送POST请求"
        #echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接已恢复,发送POST请求" >>$NETWORK_CHECK_LOG_FILE
        # 使用curl发送POST请求到 http://aaa.com
        # curl -X POST http://baidu.com
        #fi
        echo "0" >$NETWORK_CHECK_COUNTER_FILE
    fi
}

# 计数器检查函数
function check_counter() {
    COUNTER=$(cat $NETWORK_CHECK_COUNTER_FILE)
    if [[ $COUNTER -ge $COUNTER_THRESHOLD ]]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') 计数器值大于等于 $COUNTER_THRESHOLD ,等待 $RESTART_INTERVAL 秒后重新检测网络连接"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 计数器值大于等于 $COUNTER_THRESHOLD ,等待 $RESTART_INTERVAL 秒后重新检测网络连接" >>$NETWORK_CHECK_LOG_FILE
        sleep $RESTART_INTERVAL # 等待
        echo "$(date '+%Y-%m-%d %H:%M:%S') 等待 $RESTART_INTERVAL 秒后,开始重新检测网络" >>$NETWORK_CHECK_LOG_FILE
        check_network
    else
        check_network
    fi
}

check_counter

echo "$(date '+%Y-%m-%d %H:%M:%S') network 检查完毕"

部署

1、将该脚本放在openwrt任意一个目录,我这里是放在 /data/shell/目录下
2、添加执行权限 chomd +x ./network-check.sh
3、执行crontab -ecrontab 中追加一行 */2 * * * * /data/shell/network-check.sh 2分钟执行一次检测
4、添加完成后,我们在openwrt后台的计划任务列表里面就可以看到了,也可以直接通过计划任务列表去添加

有关openwrt 断网重启检测脚本的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  7. ruby - 确定 ruby​​ 脚本是否已经在运行 - 2

    有没有一种简单的方法可以判断ruby​​脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免

  8. ruby - ruby 脚本可以预编译成二进制文件吗? - 2

    我正在开发一个Ruby脚本,需要在没有Ruby解释器的情况下部署到系统上。它将需要在使用ELF格式的FreeBSD系统上运行。我知道有一个ruby​​2exe项目可以编译在Windows上运行的ruby​​脚本,但是在其他操作系统上这样做容易吗?甚至可能吗? 最佳答案 您是否检查过Rubinius或JRuby是否允许您预编译您的代码? 关于ruby-ruby脚本可以预编译成二进制文件吗?,我们在StackOverflow上找到一个类似的问题: https://

  9. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  10. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

随机推荐