crontab无法补跑关机期间错过的任务,真正负责开机补跑的是anacron;它由crontab或systemd触发,根据时间戳判断并执行逾期任务,需正确配置/etc/anacrontab、确保anacron被启动且spool目录可写。

crontab 本身无法补跑关机期间错过的任务——它只在系统运行时按时间点触发,一旦错过就永久跳过。真正负责“开机补跑”的是 anacron,而它和 crontab 不是并列关系,而是协同配合:crontab(或 systemd)负责定期启动 anacron,anacron 再根据时间戳判断是否补执行。
要让服务器在临时关机后自动补跑任务,关键不是“在 crontab 里写 anacron”,而是让 anacron 正常被触发,并正确配置其任务。以下是实际可行的要点:
✅ 确保 anacron 被系统启动机制调用
anacron 不是守护进程,不会常驻内存,必须靠外部触发。常见方式有两种:
-
通过 cron 触发(最通用)
系统级 crontab(/etc/crontab或/etc/cron.d/下文件)中通常已有这一行:0 1 * * * root /usr/sbin/anacron -s
这表示每天凌晨 1 点运行一次 anacron,检查并补跑 overdue 的任务。
⚠️ 但注意:如果服务器每天关机时间早于凌晨 1 点(比如晚上 10 点关机),这个 cron 就永远触发不了——补跑就失效。 -
通过 systemd 服务开机启动(推荐用于边缘/不常开机设备)
启用anacron.service,确保它在开机时立即运行:sudo systemctl enable anacron sudo systemctl start anacron
这样只要开机,
anacron就会立刻检查/var/spool/anacron/中的时间戳,并对逾期任务延迟执行(如配置了5分钟延迟,就等 5 分钟后跑)。
✅ 正确配置 /etc/anacrontab
这是补跑逻辑的核心。每行格式为:周期(天) 延迟(分钟) 任务名 命令
例如:
7 10 backup-weekly /usr/local/bin/weekly-backup.sh 1 5 logrotate-daily /usr/sbin/logrotate /etc/logrotate.conf
关键细节:
- 周期单位只能是天(anacron 不支持小时/分钟级)
-
命令必须用绝对路径(
crontab中可依赖 PATH,anacron 不保证环境变量) -
建议脚本开头显式设置环境:
#!/bin/bash export PATH="/usr/local/bin:/usr/bin:/bin" # 后续命令...
✅ 处理边缘场景的实操加固
针对开机后网络未就绪、磁盘忙、权限异常等常见问题:
-
网络依赖任务加重试
比如上报心跳:until curl -sf http://center/api/heartbeat; do sleep 10; done
-
降低资源争抢
在命令前加调度控制:ionice -c 3 nice -n 19 /usr/local/bin/backup.sh
-
只读根文件系统需挂载可写 spool 目录
若/var/spool/anacron/所在分区只读,时间戳无法更新,补跑将始终失败。应将其挂载为 tmpfs 或绑定到可写分区:echo "tmpfs /var/spool/anacron tmpfs defaults,noatime,nosuid,nodev 0 0" | sudo tee -a /etc/fstab sudo mount /var/spool/anacron
✅ 验证补跑是否生效
别等真断电,主动测试:
修改时间戳(如把
backup-weekly文件内容改成 10 天前的日期)重启系统
-
查看日志:
journalctl -u anacron -n 30 --no-pager | grep -i "run\|started"
应看到类似
Will run job backup-weekly或Job started backup-weekly 检查
/var/log/syslog或/var/log/messages,排除Permission denied(SELinux 未放行)等错误
不复杂但容易忽略











