cron服务常未运行,需用systemctl status确认并启用;任务需日志验证是否加载;环境变量缺失是执行失败主因,应显式声明PATH或用bash -lc;脚本须有执行权限、绝对路径并记录完整日志。

确认 cron 服务是否真在运行
很多“任务没执行”问题,根源其实是 crond 根本没跑起来——尤其在最小化安装或容器环境中,cron 服务默认可能未启用。
- 用
systemctl status cron(Debian/Ubuntu)或systemctl status crond(RHEL/CentOS)直接看状态,别只信ps aux | grep cron - 若显示
inactive (dead),立刻启动:sudo systemctl start cron - 务必补上开机自启:
sudo systemctl enable cron,否则重启后又失效 - 注意:普通用户无权启停服务,
service crond start在非 root 下会静默失败
查日志:先看 cron 是否“认出”了你的任务
任务写进 crontab -e 不等于被加载。cron 只在重载配置或服务启动时读取一次,且日志里必须出现 CRON 和 CMD 才算真正触发过。
- 查执行痕迹:
sudo journalctl -u cron | grep "CMD" | tail -10(systemd 系统) - 或翻传统日志:
sudo grep CRON /var/log/syslog(Ubuntu)或sudo tail -50 /var/log/cron(CentOS) - 如果日志里压根没你脚本的路径,说明:任务没生效(语法错/没保存)、用户权限被
/etc/cron.deny拦住、或 crontab 文件被覆盖(如用crontab /path/to/file覆盖了原内容)
环境变量缺失:90% 的“手动能跑,cron 不行”都卡在这
cron 启动的是极简 shell(/bin/sh),PATH 只有 /usr/bin:/bin,.bashrc、.profile 全不加载——所以 python3、node、mysqldump 找不到,sudo 报 No such file or directory 都是常态。
- 最稳妥解法:在 crontab 开头显式声明环境:
SHELL=/bin/bashPATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin - 或改用
bash -lc加载登录环境:0 2 * * * bash -lc '/path/to/script.sh > /tmp/log 2>&1' - 验证方法:在脚本第一行加
echo $PATH >> /tmp/env.log,对比手动执行时的输出 - 注意:不要在脚本里盲目
. ~/.bash_profile——cron 用户家目录可能不是你预期的(如root家目录是/root,但某些服务用户家目录为空)
脚本自身问题:日志和权限才是真相
即使 cron 日志显示 CMD(...),也只代表“调用了”,不代表“成功执行”。错误全藏在脚本内部或输出里。
- 去掉重定向中的
>/dev/null 2>&1,让错误浮出水面;然后检查/var/spool/mail/root(或对应用户邮箱)是否有 cron 发来的报错邮件 - 给脚本加可执行权限:
chmod +x /path/to/script.sh;同时确认脚本里所有调用的命令、路径(如cd /data && ./app)都是绝对路径 - 强制记录完整执行流:
0 * * * * /path/to/script.sh >> /var/log/myscript.log 2>&1,日志里能看到每一步 stdout/stderr - 特别警惕:脚本里用了
~或$HOME,cron 下可能解析为空;用了date +%Y%m%d生成文件名,但目标目录不存在(需提前mkdir -p)
真正难缠的 case 往往是多个因素叠加:服务开着但用户被 cron.deny 拦住、PATH 不对导致命令找不到、脚本又因相对路径失败、最后还因没日志而无法定位——所以排查必须按顺序堵漏,不能只盯着某一个点反复试。










