路由器上安装docker,会更改很多网络方面的设置,在openwrt上会影响稳定性(在标准linux系统上暂时没有这个烦恼)。
脚本作用:每10分钟ping一次外网域名,假如列表中的域名全部ping不通则视为断网,连续6次检测到断网则重启系统。
在openwrt上的用法:
1,将脚本复制到/opt/ping_hosts/目录下
2,运行这行命令赋予脚本可执行权限
chmod +x /opt/ping_hosts/ping_hosts.sh
3,将此命令添加到 openwrt-启动项-最下面的启动命令里即可(在exit 0的前面)。
nohup /opt/ping_hosts/ping_hosts.sh &
注意,如果你不插网线,因为一直连不上网,它会让系统每隔60分钟重启一次,无限次数。
如果想在linux上使用,需要自行添加到开机启动,不需要任务计划,开机执行一次即可(后台,就是第三步那行命令)。
脚本内容:
#!/bin/bash
# 获取脚本名和进程号
script_name="$(basename "$0")"
pid=$(pgrep -f "$script_name")
# 如果当前已经有一个实例在运行,则退出
if [ $(echo "$pid" | wc -w) -gt 1 ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S"): Script is already running with PID $pid. Exiting." >&2
exit 1
fi
# 定义需要 ping 的域名列表
domain_list=("www.nodeseek.com" "www.baidu.com" "doh.pub" "www.microsoft.com")
# 定义连续 ping 失败次数计数器
ping_fail=0
# 定义全部 ping 失败次数计数器
all_fail=0
# 定义连续全部 ping 失败次数的最大值
max_all_fail=6
# 定义每次 ping 的间隔
ping_interval=600
# 定义重启命令
reboot_cmd="reboot"
# 定义日志文件路径
log_file="/opt/ping_hosts/ping_hosts_log"
# 定义日志保留的秒数
log_seconds=864000
# 创建日志文件(如果不存在)
touch $log_file
# 定义函数来检查并删除日志文件中的过期内容
#function delete_old_logs {
## 计算 log_seconds 秒之前的时间戳
# threshold=$(date -d "@$(($(date +%s) - $log_seconds))" +%s)
## 使用 sed 命令筛选出超出时间戳的行并写回原文件
# sed -i -e "/^20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]/!d" -e "/^$(date +%Y-%m-%d)/!d; /^$(date -d @$threshold +'%Y-%m-%d')/q" "$log_file"
#}
# ping_hosts 函数
function ping_hosts {
for domain in "${domain_list[@]}"
do
output=$(ping -c 1 "$domain")
if [ $? -ne 0 ]; then
((ping_fail++))
echo "$(date "+%Y-%m-%d %H:%M:%S"): ping $domain :超时, ping_fail=${ping_fail}" | tee -a "${log_file}"
else
time=$(echo "$output" | awk '/time=/ {print $7}' | cut -d '=' -f 2)
#echo "$(date "+%Y-%m-%d %H:%M:%S"): ping $domain :${time}ms, ping_fail=${ping_fail}" | tee -a "${log_file}"
fi
done
}
# 主循环
while true
do
# 检查是否需要删除日志文件中的过期内容
#delete_old_logs
# 将 ping 记录写入日志文件
ping_hosts
# 如果所有域名都 ping 失败
if [ $ping_fail -eq ${#domain_list[@]} ]; then
ping_fail=0
((all_fail++))
echo "$(date "+%Y-%m-%d %H:%M:%S"): 所有目标均无回复,all_fail+1,现在是 ${all_fail}" | tee -a ${log_file}
# 如果连续 ping 失败次数达到最大值,则重启系统
if [ $all_fail -eq $max_all_fail ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S"): 连续失败次数已达最大:$all_fail / ${max_all_fail}" | tee -a "${log_file}"
echo "$(date "+%Y-%m-%d %H:%M:%S"): 正在将失败次数置零,正在重启系统..." | tee -a $log_file
echo "$(date "+%Y-%m-%d %H:%M:%S")" | tee -a "${log_file}"
all_fail=0
$reboot_cmd
fi
# 等待指定时间(秒)后再次执行
sleep $ping_interval
else
# 如果有一个或多个域名可达,则将连续 ping 失败次数重置为 0
ping_fail=0
all_fail=0
#echo "$(date "+%Y-%m-%d %H:%M:%S"): 执行成功,数据已清零。 " | tee -a "${log_file}"
#echo "$(date "+%Y-%m-%d %H:%M:%S")" | tee -a "${log_file}"
# 等待指定时间(秒)后再次执行
sleep $ping_interval
fi
done