其实就是服务器直接执行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 直接阻断任务本身的收尾过程,而应该先让任务正常结束,再延迟执行重启。





Comments | NOTHING