Linux 上 cron 定时任务不跑?先查 cron 服务本身

写好一条 crontab,等到点没触发,先怀疑不是 cron 表达式的问题,是 cron 服务本身。Debian 系和 RHEL 系的服务名和日志路径都不一样,一步步查。

第一步:确认服务在跑

Debian / Ubuntu — 服务名叫 cron

systemctl status cron
sudo systemctl start cron       # 没起就启动
sudo systemctl enable cron      # 开机自启

CentOS / Rocky / AlmaLinux — 服务名叫 crond

systemctl status crond
sudo systemctl start crond
sudo systemctl enable crond

粗暴验证:

ps -ef | grep -E 'cron|crond'

看到常驻进程就没死。

第二步:确认任务被 cron 读到了

用户任务:

crontab -l              # 查看
crontab -e              # 编辑

系统级任务分散在这几处:

cat /etc/crontab
ls  /etc/cron.d/
ls  /etc/cron.{hourly,daily,weekly,monthly}/

cron 表达式必须以换行结尾——最后一条任务后没换行,很多 cron 实现会直接忽略这一条。

第三步:看日志

Ubuntu / Debian

grep CRON /var/log/syslog

或走 journalctl:

journalctl -u cron -f

CentOS / Rocky

grep CRON /var/log/cron
tail  -f  /var/log/cron
journalctl -u crond -f

日志里应该能看到每次触发的 (user) CMD (...)看不到说明 cron 根本没执行这条:检查表达式、用户、文件位置。

第四步:cron 环境是”最小 shell”

crontab 里的命令继承的 PATH 极简,通常只有 /usr/bin:/bin。写 python 会找不到,得写绝对路径:

* * * * * /usr/bin/python3 /home/user/task.py

或者在 crontab 里显式设 PATH:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * python3 /home/user/task.py

第五步:脚本挂了但看不到报错

cron 默认把 stdout/stderr 发邮件,服务器上一般没配。把输出重定向到日志:

* * * * * /path/to/task.sh >> /var/log/task.log 2>&1

>> /var/log/task.log 追加、2>&1 把 stderr 合流。看日志就能知道到底哪一步失败。

常见坑速查

现象原因
完全没触发cron 服务没起 / 表达式写错
手动跑脚本 OK,cron 跑挂PATH 缺、用户身份不同、cwd 不同
报”command not found”命令写了相对路径,改绝对路径
任务跑了但看不到结果没重定向输出,看邮件或加 >> 日志
最后一条任务没跑crontab 文件末尾没换行
系统 crontab 没生效系统级 /etc/crontab 需要用户字段

系统 crontab 和用户 crontab 的区别

/etc/crontab 每行必须写明执行用户

0 3 * * * root /root/backup.sh

crontab -e 编辑的用户 crontab 不需要,因为它已经是”这个用户”的。搞混了就没反应。

一句话总结

cron 任务不跑,按 服务状态 → 任务在不在 → 日志 → PATH → 输出重定向 五步走完。90% 的问题在 PATH 缺失或输出被吞。