auto_reboot.sh 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/bin/bash
  2. # 自动重启调度器:读取 channels.conf [auto_reboot] 段,
  3. # 按 daily/weekly 周期在指定时间触发 reboot。
  4. # 用法: ./auto_reboot.sh [-c channels.conf]
  5. # 可作为 plc_server.sh 的后台子进程,或独立 systemd 服务运行。
  6. DIR="$(cd "$(dirname "$0")" && pwd)"
  7. CONF="${CONF:-${DIR}/channels.conf}"
  8. CHECK_INTERVAL=30
  9. while [ $# -gt 0 ]; do
  10. case "$1" in
  11. -c) CONF="$2"; shift ;;
  12. *) shift ;;
  13. esac
  14. done
  15. # ---------- 解析 [auto_reboot] 段 ----------
  16. parse_auto_reboot() {
  17. local enabled=0 period="daily" time="03:00" weekday="monday"
  18. [ ! -f "$CONF" ] && return
  19. local section=0
  20. while IFS= read -r line; do
  21. local s="$line"
  22. s="${s#"${s%%[![:space:]]*}"}"
  23. case "$s" in
  24. \#*|"") continue ;;
  25. \[*)
  26. if [ "$s" = "[auto_reboot]" ]; then section=1
  27. else section=0; fi
  28. continue
  29. ;;
  30. esac
  31. [ "$section" -ne 1 ] && continue
  32. local key="${s%%=*}"; key="${key%"${key##*[![:space:]]}"}"
  33. local val="${s#*=}"; val="${val#"${val%%[![:space:]]*}"}"
  34. val="${val%"${val##*[![:space:]]}"}"
  35. val="${val%%;*}"; val="${val%%#*}"
  36. val="${val%"${val##*[![:space:]]}"}"
  37. case "$key" in
  38. enable) ABR_ENABLED="$val" ;;
  39. period) ABR_PERIOD="$val" ;;
  40. time) ABR_TIME="$val" ;;
  41. weekday) ABR_WEEKDAY="$val" ;;
  42. esac
  43. done < "$CONF"
  44. }
  45. # ---------- weekday 名字 -> tm 可用的数字(1=Mon..7=Sun) ----------
  46. weekday_to_num() {
  47. case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
  48. mon*) echo 1 ;; tue*) echo 2 ;; wed*) echo 3 ;;
  49. thu*) echo 4 ;; fri*) echo 5 ;; sat*) echo 6 ;;
  50. sun*) echo 7 ;; *) echo 0 ;;
  51. esac
  52. }
  53. # ---------- 判断当前时刻是否匹配重启条件 ----------
  54. should_reboot_now() {
  55. local cur_h cur_m cur_wday cur_time_min
  56. cur_h=$(date +%H); cur_h=${cur_h#0}
  57. cur_m=$(date +%M); cur_m=${cur_m#0}
  58. cur_wday=$(date +%u)
  59. cur_time_min=$((cur_h * 60 + cur_m))
  60. local want_h want_m
  61. want_h="${ABR_TIME%%:*}"; want_h="${want_h#0}"
  62. want_m="${ABR_TIME##*:}"; want_m="${want_m#0}"
  63. local want_time_min=$((want_h * 60 + want_m))
  64. # 时间窗口:target minute ± 1 check_interval (防止刚好错过)
  65. local low=$((want_time_min - CHECK_INTERVAL))
  66. local high=$((want_time_min + 1))
  67. [ $low -lt 0 ] && low=0
  68. if [ $cur_time_min -ge $low ] && [ $cur_time_min -le $high ]; then
  69. if [ "$ABR_PERIOD" = "weekly" ]; then
  70. local wday; wday=$(weekday_to_num "$ABR_WEEKDAY")
  71. [ "$cur_wday" -eq "$wday" ]
  72. else
  73. return 0
  74. fi
  75. else
  76. return 1
  77. fi
  78. }
  79. # ---------- main ----------
  80. parse_auto_reboot
  81. if [ "$ABR_ENABLED" != "1" ]; then
  82. echo "[auto_reboot] 未启用"
  83. exit 0
  84. fi
  85. echo "[auto_reboot] 启用: period=$ABR_PERIOD time=$ABR_TIME weekday=$ABR_WEEKDAY"
  86. while true; do
  87. if should_reboot_now; then
  88. echo "[auto_reboot] $(date '+%F %T') 触发重启..."
  89. /sbin/reboot
  90. fi
  91. sleep "$CHECK_INTERVAL"
  92. done