Cron 任务没有执行:环境、权限、时区与日志的检查表
Cron 的常见问题是运行环境与交互式 shell 不同。用绝对路径、明确日志和时区来消除不确定性。
维护者 Kevin · Ovalk
适用范围与前提
适用于传统五字段 Unix cron/Cronie;云调度器、systemd timer 与 Quartz 的语法及时区行为不同。
先确认任务所属用户及调度实现。下方 env 与 flock 示例会实际执行任务;应使用测试副本或获准的幂等任务,不要随意用计费或删除任务试运行。
常见症状
- 手动运行脚本正常,Cron 无输出
- 任务在错误时间执行
- 执行后没有预期文件或通知
1. 确认调度器真的读取了任务
核对任务安装在正确用户下,Cron 服务运行正常,且 crontab 语法和换行符有效。系统级 /etc/cron.d 文件还需要包含用户名字段。
crontab -l
systemctl status cron || systemctl status crond
grep -i cron /var/log/syslog | tail -n 302. 让脚本不依赖交互环境
Cron 通常只有很小的 PATH,也不会加载 shell profile。使用绝对解释器、绝对命令路径、显式工作目录和最小环境变量,并把 stdout/stderr 重定向到可轮转日志。
下方包含会改变系统状态的示例,执行前确认授权、范围及恢复方案。
which python3
env -i PATH=/usr/bin:/bin /bin/sh -c "/absolute/path/job.sh"3. 处理时区和并发
主机、容器、应用调度器的时区可能不同。涉及夏令时或多区域时,以 UTC 记录并用业务时区展示;再为长任务增加锁,避免上一轮未结束时重叠执行。
下方包含会改变系统状态的示例,执行前确认授权、范围及恢复方案。
date; timedatectl status
flock -n /tmp/your-job.lock /absolute/path/job.sh解读证据
| 观察结果 | 下一步检查 |
|---|---|
| 预期时间无调度日志 | 先检查服务、任务用户、语法和时区,再看应用代码;日志位置因发行版而异。 |
| 有启动记录、无结果 | 检查退出码、文件权限、工作目录、PATH 和 stderr;进程启动不代表业务完成。 |
| 重复或跳过执行 | 对照运行时长、调度间隔、锁和夏令时切换;每月 31 日并非每个月都存在。 |
说明性诊断案例
以下假设案例用于解释推理,并非客户真实事故,也不代表已在你的技术环境中测试。
报表在开发者终端正常,cron 却提示找不到配置。终端起点在项目目录,cron 则不同。只改解释器绝对路径无法修复相对配置路径;应在脚本中设置工作目录、使用配置绝对路径,并将 stderr 写入有访问控制及轮转的日志。
验证恢复
- 观察至少一次以目标用户进行的真实定时执行,验证业务结果与记录的退出码。
- 在测试环境确认故意失败会触发告警,且禁止并发的长任务不会重叠执行。
回滚与停止条件
编辑前保存原 crontab 和脚本配置。调度错误时只恢复相关任务;重跑前检查已有实例,避免重复副作用。
预防与长期修复
- 每个任务输出开始、结束、耗时和退出码。
- 为关键任务设置失败和未执行告警。
- 将 Cron 定义纳入版本控制并进行语法测试。
参考资料与纠错
请使用与你安装版本匹配的文档。以下资料解释基础行为,命令仍需结合实际环境验证。
向 Kevin 提交更正,请附页面地址、版本与脱敏复现步骤。请查看编辑原则(英文)。