Cron 定时任务不执行?先查这 6 处,多数问题 10 分钟定位
定时任务写好了,到了时间却没跑,是 Linux 运维里最常见的“静默失败”。它不报错、不弹窗,只能按顺序排查。下面这 6 处查完,多数问题 10 分钟就能定位。
一、先确认 cron 服务在跑
很多机器装完系统后 cron 根本没启动。Debian/Ubuntu 看 cron,RHEL/CentOS 看 crond:
systemctl status cron
systemctl status crond
没启动就先启动并设开机自启:
systemctl enable --now cron
再用 crontab -l 确认任务确实写进了当前用户的 crontab,而不是只写在某个临时文件里。
二、核对时间表达式和时区
先别怀疑脚本,先怀疑时间。crontab 是 5 段:分 时 日 月 周,星号代表每项都满足。常见错误是把“每天 2 点”写成 2 * * * *,那其实是每小时 2 分都跑一次。写完后用 date 对一下系统时区,云服务器默认常是 UTC,比北京时间晚 8 小时,任务“晚 8 小时执行”多半是这个原因。改时区用 timedatectl set-timezone Asia/Shanghai,改完重启 cron 服务。
三、补上环境变量和绝对路径
交互终端能跑、cron 里跑不了,九成是环境问题。cron 的 PATH 很短,HOME、PYTHONPATH 这类变量也可能没有。正确做法是:脚本里所有命令都写绝对路径,例如 /usr/bin/python3 而不是 python3;需要在脚本开头显式写 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,依赖的变量也在脚本里 export,不要指望 crontab 外面的 shell 配置。
四、检查权限、换行符和可执行位
脚本要先 chmod +x,加上可执行权限;第一行写对解释器,例如 #!/bin/bash。从 Windows 传过来的脚本常带 CRLF 换行符,bash 会报 $'\r': command not found,用 dos2unix 或 sed -i 's/\r$//' 处理后再试。
五、把输出重定向到日志,不要让它静默
默认情况下任务输出走邮件,没配邮件就等于丢了。调试期务必重定向:
*/5 * * * * /opt/backup.sh >> /var/log/backup.log 2>&1
然后 tail -f /var/log/backup.log 看实际报错。系统日志也能佐证:Debian/Ubuntu 看 grep CRON /var/log/syslog,RHEL 系看 /var/log/cron。
六、防重叠和长时间任务
任务执行时间超过间隔,下一次又启动一个,容易互相踩数据。可以在命令前加 flock 做单实例锁:
*/5 * * * * flock -n /tmp/backup.lock /opt/backup.sh >> /var/log/backup.log 2>&1
拿不到锁的第二次实例会直接退出,不会堆积。
排查顺序总结:服务在跑吗、时间写对了吗、路径和变量全吗、权限对吗、日志说什么。按这个顺序走一遍,基本不需要反复试错。如果是 systemd 的机器,也可以考虑用 timer 单元替代 cron,它的 journalctl -u xxx.service 日志更集中,适合需要依赖和重试的任务。
- 点赞
- 收藏
- 关注作者
评论(0)