讲解 cron 环境、日志、任务重叠,以及 systemd service 与 timer 的配置、验证和回退。
默认选择:几行、无复杂依赖且必须兼容多种 Linux 的脚本可用 cron;需要统一日志、依赖关系、错过后补跑和状态查询时优先 systemd timer。两者本身不收费,但脚本产生的计算、网络或云资源会收费。迁移时不能让 cron 和 timer 同时运行同一任务。

cron 适合哪些任务
单机、命令简单、执行时间短,且已有明确日志和失败通知时,cron 足够可靠。使用 crontab -e 编辑当前用户任务:
crontab -e
crontab -lSHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
15 2 * * * /opt/jobs/backup.sh >> /var/log/backup-job.log 2>&1
cron 最容易踩的环境问题
- 没有交互 Shell 的 PATH、虚拟环境和工作目录。
- 使用相对路径,手工运行成功而计划任务失败。
- 输出未重定向,错误无法追踪。
- 上一次未结束,下一次再次启动。
- 误把系统时区当作业务时区。
使用 systemd timer
先创建 example-job.service:
[Unit]
Description=Example scheduled job
[Service]
Type=oneshot
User=app
WorkingDirectory=/opt/example
ExecStart=/opt/example/bin/job再创建 example-job.timer:
[Unit]
Description=Run example job daily
[Timer]
OnCalendar=*-*-* 02:15:00
Persistent=true
RandomizedDelaySec=5m
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now example-job.timer
systemctl list-timers --all
journalctl -u example-job.service -n 100
避免任务重叠
cron 可在脚本入口使用 flock 实现单实例;systemd 同一个 service 在 active 时通常不会重复启动,但仍要理解任务是否 fork、是否异步退出。数据库备份等任务还应设计超时和过期清理。
两种方式对比
| 能力 | cron | systemd timer |
|---|---|---|
| 简单周期任务 | 直接 | 需要两个单元 |
| 日志 | 需重定向 | journal 集成 |
| 依赖与身份 | 脚本自行处理 | service 明确定义 |
| 错过后补跑 | 需额外方案 | Persistent 可控制 |
验证与回退
先手工执行最终命令,再临时调整到最近时间测试。确认退出码、输出、产物和重复运行行为。删除任务前先 disable timer 或移除 crontab 条目,并确认没有正在运行的子进程。
上线前先让命令脱离交互环境
写绝对路径,明确工作目录、运行用户、时区和环境变量。先用目标用户手工执行,保存退出码。涉及备份、结算或清理的任务必须加锁,确保上一次未结束时不会再启动一份。
不执行时怎么查
- cron:查系统日志、邮件输出、PATH、换行和百分号转义。
- timer:查
systemctl list-timers、配套 service 状态和 journal。 - 时间不对:核对服务器时区与 timer 的日历表达式。
- 关机期间错过:cron 通常不会补跑,timer 是否补跑取决于明确配置。
验收与回退
先把频率临时改短,在无破坏测试数据上观察触发、锁、日志和业务结果,再恢复正式频率。迁移时先禁用旧入口。新方案失败就停用 timer/新 cron,恢复备份配置,不能靠手工重复执行可能非幂等的任务。
Linux 定时任务怎么配置现场验收单
- 入口或命令:cron 用 crontab -e/系统 cron;timer 放 /etc/systemd/system 并配套 service
- 提交前风险:两者不单独收费,但任务产生的计算/流量收费;重复任务可能改坏数据
- 不能继续时:PATH/工作目录错、时区错、机器关机错过、任务重叠、百分号转义、timer 未启用
- 完成证据:手工运行成功,调度按预期触发,退出码/日志/锁和业务结果正确
- 退出办法:备份旧 crontab/单元;新调度先禁用旧调度,失败恢复旧配置

