cron 不执行:环境变量、时区、权限这三关先过
cron 是最容易「看起来配好了但没跑」的东西。它不读取用户的 shell 配置,PATH 只有 /usr/bin:/bin,工作目录是用户 home。
于是脚本里所有相对路径和裸命令都会失败,而错误输出默认发邮件——现在多数服务器没配邮件,等于静默失败。
先说结论
用绝对路径,重定向日志,先验证环境差异。 把 2>&1 写到文件,比猜一百次有用。
- 命令写绝对路径,或脚本开头显式 export PATH
- 每分钟跑一次测试,输出重定向到文件
- 检查 crontab 语法与用户(root 与普通用户分开)
- 确认 cron 服务在跑、时区正确
- 复杂任务改用 systemd timer
先把问题说清楚
cron 的时间按系统时区解释;容器里常是 UTC,于是「每天 9 点」实际是北京时间 17 点。
有些系统 cron 默认不发邮件(缺 MTA),错误输出直接丢弃,看起来就像没执行。
具体怎么做
按顺序执行,每步都验证完再进下一步:
- 在脚本第一行加 #!/bin/bash,并显式设置 PATH 与 cd 到脚本目录
- 临时改成 * 测试,命令后加 >> /tmp/cron-test.log 2>&1
- 确认服务状态:systemctl status cron(或 crond)
- 检查 /var/log/cron 或 journalctl -u cron 是否有执行记录
- 复杂依赖改用 systemd timer:OnCalendar 更直观,日志进 journal
参数与成本对照
把关键数值摊开,方便判断该选哪条路:
| 现象 | 原因 | 处理 |
|---|---|---|
| 完全没执行 | cron 服务没跑/语法错 | 看服务状态与日志 |
| 执行但报错 | PATH/工作目录不对 | 绝对路径 + cd |
| 时间不对 | 时区差异 | timedatectl 核对 |
| 权限失败 | 用户不对/SELinux | 换用户或调策略 |

几个容易踩的坑
下面这些是最常见的错误做法:
- 在 crontab 里写 source ~/.bashrc:cron 用的是 /bin/sh
- 用 % 号不转义:cron 会当成换行
- 日志不重定向:出错也不知道
- 把长任务放在 cron 里跑却不加锁,导致重叠执行
最后补两句
判断标准很简单:cron 里跑的命令,必须在「没有任何环境变量」的前提下也能跑通。
工具是手段,理解机制才是能力。命令记不住没关系,知道「该看什么」就够了。
评论 (3)
照着做了一遍,确实少走弯路。第二步最容易漏,建议顺手加个检查清单。
比「一键脚本」有用多了,知道为什么比知道怎么做重要。
补充一句:不同版本行为会变,动手前先确认自己的版本号。
发表评论