关于宝塔定时重启任务日志不更新的问题记录及解决方案


其实就是服务器直接执行reboot了,然后他日志是命令执行后再记录的,那都关机了,自然没有日志记录嘛。

关于宝塔面板定时重启任务日志不更新的问题记录及解决方案

问题背景:
在云服务器上通过宝塔面板设置了一个每天定时执行的 reboot 任务。任务在宝塔面板中显示“执行成功”,服务器实际上也每天正常重启,但是宝塔计划任务的执行日志却一直停留在 5月31日,之后即使服务器每天都重启,日志时间也没有更新。

经过一系列排查,最终发现问题并不是定时任务没有执行,而是 reboot 导致宝塔任务进程在完成日志记录之前就被服务器重启中断。通过增加一个短暂的延迟,让宝塔先完成任务记录,再执行 reboot,问题得到解决。

零、图文

注:该图由ChatGPT生成。

一、问题现象

我的云服务器上设置了一个宝塔计划任务,每天 12:40 自动执行服务器重启。

最初的任务配置类似:

40 12 * * * /www/server/cron/0b996be098dac41d7999728120a3822b

也就是说,每天 12:40,宝塔会执行对应的 Shell 脚本。

服务器运行一段时间后,我发现了一个奇怪的现象:

  • 宝塔计划任务显示每天都执行成功
  • 服务器实际上也确实每天进行了重启
  • 通过 Linux 的 last reboot 可以看到服务器持续有重启记录
  • 但是宝塔计划任务里的最后执行日志却一直停留在 5 月 31 日
  • 即使到了 7 月,宝塔的日志时间依然没有变化

这就产生了一个疑问:

任务到底有没有执行?如果执行了,为什么宝塔的日志不更新?


二、首先确认服务器到底有没有重启

由于宝塔日志可能存在问题,所以第一步不是继续修改脚本,而是直接从 Linux 系统层面确认服务器是否真的发生了重启。

执行:

last reboot

可以看到系统的历史启动记录。

执行last reboot命令

[root@xx ~]# last reboot
reboot   system boot  4.18.0-193.14.2. Wed Jul 22 20:40  still running
reboot   system boot  4.18.0-193.14.2. Wed Jul 22 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Tue Jul 21 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Tue Jul 21 13:24 - 12:40  (-00:44)
reboot   system boot  4.18.0-193.14.2. Mon Jul 20 20:40 - 05:24  (08:44)
reboot   system boot  4.18.0-193.14.2. Mon Jul 20 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Sun Jul 19 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Sun Jul 19 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Sat Jul 18 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Sat Jul 18 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Fri Jul 17 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Fri Jul 17 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Thu Jul 16 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Thu Jul 16 13:23 - 12:40  (-00:43)
reboot   system boot  4.18.0-193.14.2. Wed Jul 15 20:40 - 05:23  (08:42)
reboot   system boot  4.18.0-193.14.2. Wed Jul 15 13:23 - 12:40  (-00:43)

那每天都有对应的启动记录,那么就可以证明:

服务器实际上确实发生了重启。

服务器已经重启
        ↓
说明 reboot 任务正常
        ↓
问题集中在宝塔日志记录机制

三、检查 crontab

执行crontab -l命令

继续执行:

crontab -l

输出:

[root@xxx ~]# crontab -l
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
40 12 * * *  /www/server/cron/0b996be098dac41d7999728120a3822b >> /www/server/cron/0b996be098dac41d7999728120a3822b.log 2>&1
30 6 * * *  flock -xn /www/server/cron/50e7180d6515594d52c840bd746e8155.lock -c /www/server/cron/50e7180d6515594d52c840bd746e8155  >> /www/server/cron/50e7180d6515594d52c840bd746e8155.log 2>&1

这说明每天 12:40 确实会执行对应的脚本。

同时还可以看到其他计划任务,例如:

30 6 * * * flock -xn /www/server/cron/50e7180d6515594d52c840bd746e8155.lock -c /www/server/cron/50e7180d6515594d52c840bd746e8155

这类任务与 reboot 无关,因此需要分别判断。

到这里可以确认:

12:40 的计划任务本身是存在的。


四、检查宝塔实际执行的脚本

接下来查看:

cat /www/server/cron/0b996be098dac41d7999728120a3822b

原来的脚本大致是:

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo $$ > /www/server/cron/0b996be098dac41d7999728120a3822b.pl

reboot

echo "----------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "[$endDate] Successful"
echo "----------------------------------------"

if [[ "$1" != "start" ]]; then
    btpython /www/server/panel/script/log_task_analyzer.py /www/server/cron/0b996be098dac41d7999728120a3822b.log
fi

rm -f /www/server/cron/0b996be098dac41d7999728120a3822b.pl

这时候问题就非常明显了。

脚本执行顺序是:

执行脚本
   ↓
执行 reboot
   ↓
服务器开始重启
   ↓
服务器进程被终止
   ↓
后续代码无法正常执行
   ↓
Successful 日志无法正常完成

而原脚本中真正负责记录成功状态的代码却在:

reboot

之后:

echo "[$endDate] Successful"

这就产生了一个非常典型的问题。


五、为什么服务器重启了,但是宝塔日志没有更新?

核心原因就是:

reboot 是一个会直接导致当前系统进入重启流程的操作。

当宝塔计划任务直接执行:

reboot

时,实际流程更接近:

宝塔计划任务开始
       ↓
执行 Shell 脚本
       ↓
执行 reboot
       ↓
系统开始重启
       ↓
当前 Shell 进程被终止
       ↓
宝塔无法正常完成任务收尾
       ↓
宝塔任务日志无法正常更新

因此:

服务器重启成功

和:

宝塔任务日志记录成功

实际上是两件不同的事情。

服务器可以已经成功重启,但是宝塔的任务日志却没有来得及记录。

这也解释了为什么:

last reboot

可以看到最新的重启记录,而宝塔任务日志却仍然停留在 5 月 31 日。


六、直接修改成 reboot 仍然不能解决问题

最初可能会认为:

#!/bin/bash
/sbin/reboot

这样就可以了。

但是实际上,这只能保证服务器重启,并不能保证宝塔计划任务日志正常更新。

因为执行过程依然是:

宝塔启动任务
   ↓
/sbin/reboot
   ↓
服务器重启
   ↓
宝塔任务进程被中断

因此:

单纯把 reboot 写得更简单,并不能解决宝塔日志的问题。

真正需要解决的是:

让宝塔先完成自己的任务记录,再执行服务器重启。


七、最终解决方案:延迟执行 reboot

最终采用的方法是:

#!/bin/bash

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Reboot scheduled"

(sleep 60; /sbin/reboot) &

exit 0

这里最关键的是:

(sleep 60; /sbin/reboot) &

以及:

exit 0

它们改变了原来的执行逻辑。

原来的逻辑:

执行任务
   ↓
reboot
   ↓
服务器重启
   ↓
宝塔无法完成日志记录

修改后的逻辑:

执行宝塔任务
   ↓
启动后台延迟任务
   ↓
sleep 60
   ↓
当前 Shell 脚本立即 exit 0
   ↓
宝塔认为任务正常结束
   ↓
宝塔记录执行成功
   ↓
等待60秒
   ↓
执行 /sbin/reboot
   ↓
服务器重启

也就是说,原来是:

先重启,再记录日志

实际上无法完成。

现在变成:

先让宝塔完成任务,再延迟重启

因此日志就可以正常更新。


八、实际测试结果

为了验证这个方案,我进行了实际测试。

将计划任务设置为:

2:16

脚本使用延迟 60 秒的方式。

实际观察结果:

2:16:00
宝塔开始执行计划任务

随后:

2:16:01
宝塔计划任务日志显示执行成功

然后:

2:17
服务器真正执行 reboot

最终服务器发生重启。

这个测试结果非常关键,因为它完整验证了整个执行链条:

2:16
    ↓
宝塔执行任务
    ↓
2:16:01
    ↓
宝塔记录任务成功
    ↓
2:17
    ↓
执行 reboot
    ↓
服务器重启

由此可以确认:

宝塔日志不更新的根本原因,并不是 reboot 没有执行,而是 reboot 执行得太早,导致宝塔还没有完成任务日志记录,服务器就已经开始重启了。


九、最终可以把延迟时间缩短吗?

可以。

经过 60 秒的测试验证后,可以确定核心问题只是需要给宝塔留出一个“任务收尾”的时间。

因此不需要真的等待 60 秒。

例如可以改成10s:

#!/bin/bash

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Reboot scheduled"

(sleep 10; /sbin/reboot) &

exit 0

最终流程就是:

12:40:00
宝塔执行任务

12:40:01
宝塔记录执行成功

12:40:10
执行 reboot

12:40:10
服务器重启

也可以尝试:

sleep 2

理论上 2 秒可能已经足够。

但是考虑到服务器负载、宝塔任务执行速度以及日志写入速度,个人更建议使用:

sleep 10

这样既不会让服务器长时间延迟重启,也给宝塔留出了足够的日志处理时间。


十、最终推荐脚本

如果需求只是:

每天通过宝塔计划任务自动重启服务器,同时希望宝塔能够正常记录每次任务的执行时间。

最终可以使用:

#!/bin/bash

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Reboot scheduled"

(sleep 10; /sbin/reboot) &

exit 0

计划任务按照原来的时间设置即可,例如:

每天 12:40 执行

最终执行逻辑:

             宝塔计划任务
                  │
                  ▼
          Shell脚本开始执行
                  │
                  ▼
        创建后台延迟重启任务
                  │
                  ├───────────────┐
                  │               │
                  ▼               ▼
           exit 0              sleep 5
                  │               │
                  ▼               ▼
       宝塔记录任务成功        等待5秒
                                  │
                                  ▼
                            /sbin/reboot
                                  │
                                  ▼
                             服务器重启

十一、问题总结

这次问题最终可以归纳为一句话:

服务器的 reboot 操作本身没有问题,真正的问题是 reboot 的执行时机。

直接执行:

/sbin/reboot

会导致服务器立即进入重启流程,宝塔计划任务来不及完成自己的日志记录,所以出现:

服务器每天正常重启
        +
宝塔日志却停留在旧日期

通过:

(sleep 10; /sbin/reboot) &
exit 0

将任务拆分成两个阶段:

第一阶段:
宝塔完成任务 → 写入日志 → 任务结束

第二阶段:
等待几秒 → 执行 reboot → 服务器重启

最终就可以同时实现:

  • 服务器定时自动重启
  • 宝塔计划任务日志正常更新
  • 可以在宝塔面板查看最近一次任务执行时间
  • 实际重启时间与任务记录时间只相差几秒

核心经验就是:对于会立即导致系统关机、重启的计划任务,如果希望任务管理平台正常记录“执行成功”,不要让 reboot 直接阻断任务本身的收尾过程,而应该先让任务正常结束,再延迟执行重启。

封面

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 关于宝塔定时重启任务日志不更新的问题记录及解决方案


三二一的一的二