You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cron执行日志检测重启脚本失败问题求助及简化方案咨询

问题解决与优化方案

原问题核心错误点

  1. Cron的timeout 5s设置完全错误:你的脚本用tail -fn0是持续实时监听日志,而timeout 5s会在5秒后强制杀死脚本,导致脚本根本来不及检测日志内容。
  2. 脚本运行模式与Cron不匹配:持续监听的脚本适合后台常驻,而非Cron每分钟调用一次——每次调用都会重新启动监听,且存活时间极短,完全起不到监控作用。
  3. 潜在的环境变量问题:Cron默认PATH不包含/sbin等系统目录,虽你脚本里写了/sbin/reboot的绝对路径,但仍建议在脚本内明确设置PATH避免其他命令报错。

修复方案一:常驻后台的实时监控脚本(推荐)

这种方式让脚本一直运行,实时跟踪日志,效率最高且响应及时:

修改后的脚本 /home/root/resetiferror.sh

#!/bin/bash
# 明确设置环境变量PATH,避免命令找不到
export PATH=/usr/bin:/bin:/sbin:/usr/sbin

# 定义日志路径
TARGET_LOG="/var/log/messages"
MONITOR_RECORD="/var/log/resetiferror"

# 实时跟踪日志,逐行检查
tail -fn0 "$TARGET_LOG" | while read -r line; do
    # 匹配关键词(忽略大小写)
    if echo "$line" | grep -qi "failed to read"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') 检测到异常,执行系统重启" >> "$MONITOR_RECORD"
        # 执行重启(用绝对路径确保可靠)
        /sbin/reboot
    fi
done

部署方式

  1. 确保脚本可执行:chmod +x /home/root/resetiferror.sh
  2. 后台启动并设置开机自启:
    • 临时启动:nohup /home/root/resetiferror.sh > /dev/null 2>&1 &
    • 永久开机自启(Systemd系统):
      创建服务文件 /etc/systemd/system/resetiferror.service:
      [Unit]
      Description=监控/var/log/messages异常并触发重启
      After=syslog.target
      
      [Service]
      Type=simple
      ExecStart=/home/root/resetiferror.sh
      Restart=always
      User=root
      
      [Install]
      WantedBy=multi-user.target
      
      启用服务:
      systemctl daemon-reload
      systemctl enable --now resetiferror.service
      

修复方案二:Cron周期性检查日志(适合非实时场景)

如果不需要实时响应,可让Cron每分钟检查一次新增的日志内容,避免重复触发:

优化后的脚本 /home/root/resetiferror.sh

#!/bin/bash
export PATH=/usr/bin:/bin:/sbin:/usr/sbin

TARGET_LOG="/var/log/messages"
MONITOR_RECORD="/var/log/resetiferror"
# 记录上次检查的日志位置,避免重复检测
POS_FILE="/var/log/resetiferror.pos"

# 初始化位置文件(首次运行时)
if [ ! -f "$POS_FILE" ]; then
    echo "$(stat -c %s "$TARGET_LOG")" > "$POS_FILE"
fi

CURRENT_SIZE=$(stat -c %s "$TARGET_LOG")
LAST_SIZE=$(cat "$POS_FILE")

# 处理日志轮转(日志文件变小的情况)
if [ "$CURRENT_SIZE" -lt "$LAST_SIZE" ]; then
    LAST_SIZE=0
fi

# 检查上次检查后新增的日志内容
tail -c +$((LAST_SIZE + 1)) "$TARGET_LOG" | grep -qi "failed to read"
if [ $? -eq 0 ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') 检测到异常,执行系统重启" >> "$MONITOR_RECORD"
    /sbin/reboot
fi

# 更新检查位置
echo "$CURRENT_SIZE" > "$POS_FILE"

Cron配置

替换原Cron任务,去掉timeout,设置每分钟运行:

* * * * * /home/root/resetiferror.sh >> /var/log/resetiferror.log 2>&1

更简便的替代思路

如果系统支持journalctl(Systemd系统),可直接用它跟踪日志,无需脚本:

journalctl -fu systemd-journald | grep -qi "failed to read" && /sbin/reboot

将此命令加入开机自启即可,逻辑和脚本一致,但更简洁。

内容的提问来源于stack exchange,提问作者twsnnl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:27:33