#!/bin/bash # 自动重启调度器:读取 channels.conf [auto_reboot] 段, # 按 daily/weekly 周期在指定时间触发 reboot。 # 用法: ./auto_reboot.sh [-c channels.conf] # 可作为 plc_server.sh 的后台子进程,或独立 systemd 服务运行。 DIR="$(cd "$(dirname "$0")" && pwd)" CONF="${CONF:-${DIR}/channels.conf}" CHECK_INTERVAL=30 while [ $# -gt 0 ]; do case "$1" in -c) CONF="$2"; shift ;; *) shift ;; esac done # ---------- 解析 [auto_reboot] 段 ---------- parse_auto_reboot() { local enabled=0 period="daily" time="03:00" weekday="monday" [ ! -f "$CONF" ] && return local section=0 while IFS= read -r line; do local s="$line" s="${s#"${s%%[![:space:]]*}"}" case "$s" in \#*|"") continue ;; \[*) if [ "$s" = "[auto_reboot]" ]; then section=1 else section=0; fi continue ;; esac [ "$section" -ne 1 ] && continue local key="${s%%=*}"; key="${key%"${key##*[![:space:]]}"}" local val="${s#*=}"; val="${val#"${val%%[![:space:]]*}"}" val="${val%"${val##*[![:space:]]}"}" val="${val%%;*}"; val="${val%%#*}" val="${val%"${val##*[![:space:]]}"}" case "$key" in enable) ABR_ENABLED="$val" ;; period) ABR_PERIOD="$val" ;; time) ABR_TIME="$val" ;; weekday) ABR_WEEKDAY="$val" ;; esac done < "$CONF" } # ---------- weekday 名字 -> tm 可用的数字(1=Mon..7=Sun) ---------- weekday_to_num() { case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in mon*) echo 1 ;; tue*) echo 2 ;; wed*) echo 3 ;; thu*) echo 4 ;; fri*) echo 5 ;; sat*) echo 6 ;; sun*) echo 7 ;; *) echo 0 ;; esac } # ---------- 判断当前时刻是否匹配重启条件 ---------- should_reboot_now() { local cur_h cur_m cur_wday cur_time_min cur_h=$(date +%H); cur_h=${cur_h#0} cur_m=$(date +%M); cur_m=${cur_m#0} cur_wday=$(date +%u) cur_time_min=$((cur_h * 60 + cur_m)) local want_h want_m want_h="${ABR_TIME%%:*}"; want_h="${want_h#0}" want_m="${ABR_TIME##*:}"; want_m="${want_m#0}" local want_time_min=$((want_h * 60 + want_m)) # 时间窗口:target minute ± 1 check_interval (防止刚好错过) local low=$((want_time_min - CHECK_INTERVAL)) local high=$((want_time_min + 1)) [ $low -lt 0 ] && low=0 if [ $cur_time_min -ge $low ] && [ $cur_time_min -le $high ]; then if [ "$ABR_PERIOD" = "weekly" ]; then local wday; wday=$(weekday_to_num "$ABR_WEEKDAY") [ "$cur_wday" -eq "$wday" ] else return 0 fi else return 1 fi } # ---------- main ---------- parse_auto_reboot if [ "$ABR_ENABLED" != "1" ]; then echo "[auto_reboot] 未启用" exit 0 fi echo "[auto_reboot] 启用: period=$ABR_PERIOD time=$ABR_TIME weekday=$ABR_WEEKDAY" while true; do if should_reboot_now; then echo "[auto_reboot] $(date '+%F %T') 触发重启..." /sbin/reboot fi sleep "$CHECK_INTERVAL" done