全部排错手册
系统 / 调度更新于 4 分钟阅读 · 执行耗时因环境而异

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 30

2. 让脚本不依赖交互环境

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 提交更正,请附页面地址、版本与脱敏复现步骤。请查看编辑原则(英文)