crontab 定时任务没跑起来?先按这 5 处排查
脚本在终端里能跑,放到 crontab 里却没反应,这种情况很常见。cron 的运行环境和交互式 Shell 差别很大,排查要先分清是“没触发”还是“触发了但失败了”,再按下面五处逐项缩小范围。
一、环境变量缺失
cron 启动任务时只带一个极简环境,PATH 通常只有 /usr/bin:/bin,/usr/local/bin 和用户自装的工具目录都不在其中。于是手动执行正常,放到 crontab 里就报 command not found,有时还会静默走错分支,日志里看不到明显错误。
稳妥的做法是给命令写绝对路径,例如把 python 改成 /usr/local/bin/python3,把脚本改成 /opt/scripts/backup.sh;也可以在脚本开头 source /etc/profile,或显式导出需要的变量。不要假设 cron 和你的终端拥有同样的环境。
二、权限与换行问题
出现 Permission denied 时,先检查脚本是否有执行权限,文件必须可执行,且属主应与 cron 运行用户一致;没有执行权限时,可临时用 sh /path/to/script.sh 调用,但规范做法仍是 chmod +x 补上权限。
另一类问题来自换行符。在 Windows 下编辑后传到 Linux 的脚本,行尾可能带有 \r,Shell 会把它当作命令的一部分,报出 $‘\r’: command not found。先用 cat -A 检查行尾,或用 dos2unix 转换格式后再测试。
三、日志定位
任务失败后查无对证,多半是输出没有落盘。cron 默认把输出发邮件,大多数服务器上这封邮件没人看,等于丢了。应在 crontab 里把输出重定向到文件,例如在命令末尾加上 >> /var/log/backup.log 2>&1,并按日期轮转,避免单个文件无限增大。
系统日志也要会找。常见位置是 /var/log/cron,有的系统交给 systemd 管理,可用 journalctl -u cron 或 journalctl -u crond 查看。先确认 cron 是否在预定时间尝试执行,再看任务自身的日志,两者结合才能判断是调度问题还是脚本问题。
四、时间表达式写错
crontab 五个域依次是分、时、日、月、星期。*/5 表示每 5 分钟执行一次,而单独写 5 表示每小时第 5 分钟执行一次,两者差别很大,初学者常把前者误读成后者。
同时指定日期与星期时也容易误读。例如一行里同时写了“每月 1 日”和“星期一”,cron 采用“或”逻辑:每月 1 日会执行,每个星期一也会执行,而不是只有既是 1 日又是星期一那天才执行。想表达“每月第一个星期一”,需要额外用日期判断配合。写完后不要只靠脑算,测试阶段可把间隔临时改短,观察一两次触发情况再改回正式周期。
五、服务本身未运行
如果所有任务都不执行,可能是 cron 服务本身停了。系统重启、配置变更或误操作都可能导致服务停止。先用 systemctl status cron 检查,有的发行版服务名是 crond,对应 systemctl status crond;停了就用 systemctl start 启动,并用 systemctl enable 设置开机自启。
修改 crontab 后通常不用手动重启,cron 会自动重新加载。但在容器或极简环境中,还要确认是否安装并启动了 cron,很多精简镜像默认并不包含它。
检查清单
按这个顺序过一遍:确认 cron 服务在运行;核对时间表达式和下一次触发时间;检查脚本的绝对路径、执行权限和换行符;在脚本开头补齐环境变量;把输出重定向到日志文件,根据日志区分调度问题还是脚本问题。逐一排除后,大多数 cron 故障都能较快定位。
- 点赞
- 收藏
- 关注作者
评论(0)