crontab不执行绝大多数因环境问题而非服务故障,需用crontab -l确认任务写入、env -i模拟cron环境、重定向日志捕获错误,再检查服务状态、用户权限、selinux及脚本执行权。

crontab 不执行,绝大多数情况不是 cron 本身坏了,而是任务在它那个极简环境里“站不稳”。直接看日志、模拟执行、比对环境,三步就能定位八成问题。
怎么看 cron 有没有真正加载你的任务?
很多人改完 crontab -e 就以为生效了,但编辑器可能没写入、时间戳没更新、甚至临时文件残留导致 crontab 文件被截断。
- 必须用
crontab -l确认内容已真实写入——别信编辑器的“:wq”提示 - 检查输出里有没有语法错误,比如某行末尾多了一个空格,或
#写在时间字段后(整行会被当注释丢弃) - 时间字段顺序是
分 时 日 月 周,不是“年月日时分”,0 2 * * 1是每周一凌晨 2 点,不是每月 1 号 - 日和周是 or 关系:
0 2 1 * 1表示“每月 1 号”或“每周一”,满足其一就执行,容易重复
为什么脚本手动能跑,cron 里就报 command not found?
因为 cron 默认只继承极窄的环境:PATH=/usr/bin:/bin,HOME、SHELL、JAVA_HOME 全都不带,~ 展开失败,.bashrc 完全无效。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 在
crontab文件最顶部显式声明变量:PART=/usr/local/bin:/usr/bin:/bin,HOME=/home/username - 所有命令用绝对路径:
/usr/bin/python3而不是python3,/home/user/script.sh而不是~/script.sh - 脚本开头加
cd /home/user或os.chdir('/home/user'),避免相对路径失效 - 想验证环境差异?用这句模拟 cron 执行:
sudo -u username env -i PATH=/usr/bin:/bin /usr/bin/python3 /path/to/script.py
怎么捕获静默失败的日志?
cron 默认不记录 stderr,Python 导入失败、权限拒绝、网络超时……全被吞掉,你连错在哪都不知道。
- 每条 crontab 条目必须加日志重定向:
51 7 * * * /usr/bin/python3 /home/user/script.py >> /home/user/script.log 2>&1 -
2>&1的意思是“把标准错误(2)重定向到当前标准输出(1)指向的位置”,二者都进同一个文件 - 日志文件目录要确保用户有写权限;如果写
/tmp,注意某些系统会定期清理 - 顺手查系统级 cron 日志:
sudo grep CRON /var/log/syslog(Ubuntu/Debian)或sudo journalctl -u crond -n 50(RHEL/CentOS)
还有哪些容易被跳过的硬性限制?
服务没启、用户被禁、SELinux 拦着、脚本没权限……这些不是“环境问题”,是直接卡死执行链的开关。
- 先确认服务活着:
systemctl status cron(Debian/Ubuntu)或systemctl status crond(RHEL/CentOS) - 检查用户是否被拉黑:
/etc/cron.deny里有没有你用户名;若存在/etc/cron.allow,你必须在里面 - 脚本得有执行权:
chmod +x /path/to/script.sh;如果用了 shebang(如#!/usr/bin/env python3),这步不能省 - 云服务器(如 Amazon Linux EC2)或启用了 SELinux 的系统,临时用
sudo setenforce 0测试是否被策略拦截
真正的难点不在“怎么配”,而在“怎么证”:你得证明那条命令在 cron 的上下文里确实能跑通——不是靠猜,是靠 env -i 模拟、靠 2>&1 抓日志、靠 crontab -l 看真实内容。漏掉任意一环,排查就变成玄学。










