近期发现家里软路由偶现掉线的问题,又查不出什么原因,网络讨论有说升级系统的、换网线的,疲于折腾,不如写一个脚本放在定时任务检查网络状态,管他什么掉线的问题,我能接受短时间内掉线后网络自愈。而在 openwrt 环境,shell 脚本是不二之选,这种语言就像笔头下的字,提笔就忘,但又全认识,自己写嘛也能翻着手册花上小半天搓出来。这不是有 chatGPT 嘛,经过十几次的需求描述和反复,chatGPT 帮我写了一个还算满意的脚本。
以下是我描述需求的内容:
用 shell 脚本实现如下需求:
- 定时任务每 30 分钟执行一次本脚本
- 检查网络情况,如果成功,在本地文件日志追加一条成功记录,记录内容为时间、动作是成功
- 如果检查到网络失败,在本地文件日志中追加一条失败记录,记录内容为时间、动作是失败、失败次数
- 失败后,等待 30 秒再重试检查网络,并读取本地日志最后一条记录,如果是失败日志,并且失败次数小于 10,继续重试;
- 如果本地日志最后一条记录是失败的,且失败次数满足 10 次,尝试重启 openwrt 的 WAN 口网络
- 重启成功后,在本地文件日志追加一条重启日志,记录内容为时间、动作是重启
以下是 chatGPT 最终生成的脚本内容:
#!/bin/sh
log_file="./status.log"
max_retries=10
retry_interval=30
check_url="baidu.com"
check_network() {
ping -c 1 $check_url > /dev/null
if [ $? -eq 0 ]; then
echo "$(date) - Success" >> $log_file
else
retry=1
while [ $retry -le $max_retries ]; do
echo "$(date) - Failure, Retry: $retry" >> $log_file
sleep $retry_interval
ping -c 1 $check_url > /dev/null
if [ $? -eq 0 ]; then
echo "$(date) - Success" >> $log_file
break
fi
retry=$((retry + 1))
done
if [ $retry -gt $max_retries ]; then
# Restart WAN interface
# /etc/init.d/network restart
ifup wan
if [ $? -eq 0 ]; then
echo "$(date) - Restart" >> $log_file
fi
fi
fi
}
check_network
openWRT 软路由 WAN 口的重启方法,可以使用 ifup wan
,而不建议使用 /etc/init.d/networks restart
,因为我在软路由查看日志时,发现掉线的总是 WAN 口导致 DNS 无法工作。
之后在计划任务中添加脚本的执行:
*/30 * * * * /your/script/path/network_checker.sh