cron 任务不执行怎么排查修复?
cron 不跑的排查顺序:crond 服务在不在 → cron 日志看有没有触发 → 时间格式与全角字符 → 环境变量/PATH 差异 → 脚本权限与 shebang。本文给出逐步排查法。
按以下六步收集证据:①cron 服务在跑吗(systemctl status cron);②看日志确认触发没(grep CRON /var/log/syslog);③手动跑一遍命令(排除脚本本身问题);④检查 PATH 与环境变量差异(cron 环境极简);⑤查时间格式与不可见字符;⑥看脚本权限与解释器。
① cron 服务状态
systemctl status cron # Debian/Ubuntu;RHEL 系是 crond
sudo systemctl start cron && sudo systemctl enable cron
② 看 cron 日志确认触发
grep CRON /var/log/syslog # Debian/Ubuntu
grep CROND /var/log/cron # RHEL/CentOS
journalctl -u cron --since today
- 日志里有调度记录但没看到效果 → 调度器已尝试执行,继续检查输出、退出码和业务结果
- 当前日志没有记录 → 先核对日志去向、级别和保留范围,再查是否触发及格式
③ 手动跑一遍
把任务命令原样在终端执行。能跑≠cron 里能跑(环境不同),手动失败也可能来自另一套环境,须用相同用户、目录和变量复现。
④ 环境差异(最高频根因)
cron 的环境变量极简:有实现提供的 PATH 等环境,但通常不读取交互 shell 的 .bashrc,不能假定与终端一致。
# 在 crontab 顶部显式设 PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
任务里:命令用绝对路径(/usr/bin/python3 而不是 python3),脚本内同理。
⑤ 格式与隐藏字符
- 五段时间是否合法(
crontab -l复核) - 从文档复制的全角空格/星号:
crontab -l | cat -A现形 - 行尾换行、
%未转义(cron 里 % 表示换行,写\%)
⑥ 权限与解释器
ls -l /app/jobs/job.sh # 有执行位吗(x)
head -1 /app/jobs/job.sh # shebang 正确吗(#!/bin/bash)
输出要接住
*/10 * * * * /app/jobs/job.sh >> /var/log/job.log 2>&1
没重定向的输出通常交给邮件系统,未配置投递时容易遗漏。让脚本记录任务名、开始时间、结束时间和退出码;用 DataKit 日志采集汇入观测云后,可按任务名与计划时间查找结果,区分未触发、执行失败和仍在运行。
常见问题(FAQ)
Q:手动能跑 cron 里不行,优先查什么?
A:环境变量。核对所需 PATH、工作目录、用户和少量非敏感配置;不要把全部 env 写入 /tmp,可能泄露密钥。
Q:容器里的 cron 不跑?
A:容器里 cron 可能没前台运行或根本没装;详见本系列容器 cron 篇。K8s 用 CronJob。
Q:任务跑了一半被杀了?
A:查内存(OOM Killer,dmesg 可见)与执行时长(下个周期叠加),长任务加锁防重入(flock)。