首页/系统/Linux 运维命令速查/场景:cron 任务不执行 8 步排查
定时任务与计划50 条

场景:cron 任务不执行 8 步排查

从「有没有被触发」到「触发后为何失败」逐层排查:服务状态、日志、格式、权限、环境、命令路径、脚本执行位、输出重定向。

Linux 运维命令速查系统更新于 2026-10-13

这个场景要解决什么

任务到点没动静,排查要分两段:先确认它有没有被触发,再确认触发之后为什么失败。这两段彼此独立,混在一起查会绕圈——很多时候任务根本没被调度,此时讨论脚本内部逻辑就是白费工夫。按下面的顺序走,每一步都能给出一个二选一的结论,八步之内通常能锁定原因。

基本信息

适用场景任务表里的任务没有按预期执行,或执行了却没有产出
方法分层验证:触发链(服务、日志、格式、任务表)→ 执行链(环境、权限、路径、脚本)
输出形式每一步一条可直接复制的命令
前提知道任务属于哪个用户,以及任务表文件的位置

第 1-4 步 触发链

第 1-4 步 触发链
systemctl is-active cron 2>/dev/null || systemctl is-active crond   # 1 服务在跑?
sudo grep CRON /var/log/syslog | tail -n 5                          # 2 日志见触发?
sudo journalctl -u cron --since '30 min ago' | tail -n 5            # 3 journal 兜底
crontab -l | cat -A | sed -n '1,20p'                                # 4 有无隐藏字符与语法错

第 5-8 步 执行链

第 5-8 步 执行链
sudo ls -l /var/spool/cron/crontabs/root                            # 5 任务表存在且权限对?
env -i PATH=/usr/bin:/bin /bin/sh -c '/opt/app/job.sh; echo rc=$?'  # 6 空环境手动跑
ls -l /opt/app/job.sh                                               # 7 执行位与 shebang
bash -x /opt/app/job.sh 2>&1 | tail -n 30                           # 8 带追踪复跑

分层排查对照

层要回答的问题典型症状
服务层cron 守护进程在运行吗所有任务都不执行
触发层到点有没有被唤起个别任务不动,日志里没有任何记录
格式层任务表能不能被解析报语法错误,或整张表被忽略
任务表层文件在不在,属主与权限对不对某个用户的任务全部不执行
环境层PATH、SHELL、变量是否齐备手工能跑,cron 里报命令找不到
权限层有没有执行位与文件访问权报 Permission denied
逻辑层脚本内部是否真的执行成功有执行记录,但没有预期产出

常见根因排序

  • 环境与 PATH 差异,占大多数情况
  • 权限与执行位问题
  • 任务表里的隐藏字符或语法错误
  • 依赖的服务、网络或挂载还没就绪
  • 脚本没有重定向输出,出错信息被直接丢弃
判断有没有触发只认日志:cron 每执行一条任务都会在系统日志里留下记录。日志里没有对应记录,就说明问题出在触发侧而不是脚本里。
临时加一条每分钟执行的观测任务(例如把 env 导出到文件)能快速看清 cron 的真实环境,但务必用后立即删除,否则它会长期占用资源并污染日志。

快速自检的三条命令

  • crontab -l 里搜任务关键词,确认条目还在,并且没有被注释掉
  • 用 systemctl list-timers 与 crontab -l 区分这条任务到底归 cron 还是 systemd timer
  • 在目标机上执行 date,确认时间与时区正确,时钟漂移会让「到点」变得不确定
把任务的输出统一重定向到文件(>> /var/log/job.log 2>&1),是让下一次排查少走弯路最划算的一次改动。
排查期间临时改成每分钟执行确实方便,但会放大脚本本身的副作用;对会写数据库或发通知的任务,先在测试环境验证逻辑,再回到原计划频率。
日志位置随发行版不同:Debian 系常见 /var/log/syslog 里的 CRON 记录,RHEL 系在 /var/log/cron。只在新系统上找 syslog,很容易误判成「没有日志」。
如果任务写在 /etc/cron.d 或系统级 crontab 里,排查时别忘了它们比用户任务表多一个用户字段;用 crontab -l 看不到这些条目,得直接读文件。

观测动作与风险

动作能确认什么风险
导出运行环境调度时的真实变量与路径需立即删除,否则长期占用
临时改为每分钟触发链路是否通畅脚本副作用被同步放大
输出重定向到文件失败原因与退出码需控制文件增长
空环境手工执行是否只是环境差异不代表调度时刻的状态
查看触发日志任务是否被调度日志位置随发行版不同
定位到根因后要把改动固化:把环境变量、绝对路径、输出重定向与失败告警写进任务定义,再按原计划频率恢复执行,并把这次的结论写进任务说明里。否则下次换人排查时,同样的八步还要再走一遍,前面的时间就白花了。

易错点

  • 日志系统不完整时把「没记录」误判成「没触发」,先确认这台机器该看哪个日志源
  • 在 Windows 上编辑后上传的任务表带 CRLF,cat -A 会显示 ^M,任务被静默忽略或直接报错
  • 只在交互 shell 里测过脚本,没在空环境下跑过,环境差异要等上线才暴露
  • 脚本没有执行位或 shebang 写错,日志里有触发记录但进程立刻失败
  • 任务的实际执行用户与设想不同,文件权限按另一个身份判定而失败
  • 只用「手工能跑」作为结案依据:手工执行成功只证明脚本本身没问题,调度侧的环境、权限与时序差异仍需逐项排除后才能收工

数据来源与参考

  • man 5 crontab(环境与语法)
  • RHEL 文档:cron 故障排查
  • Debian cron 文档

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌