适用读者:crontab 写了但"就是不执行"的人。
前置:S15-B06。
实测环境:Ubuntu 24.04(cron 3.0),2026-11-05。
覆盖旧文:1301(51) 1331(25) = 76 点。
覆盖扩展:E-S15-013(cron 的 PATH 与最小环境)。
上一篇:S15-J01 · 文本三剑客:grep / sed / awk 与日志分析
下一篇:S15-J03 · 抓包与网络排障。
1. 一句话结论
cron 不读你的 shell 配置(~/.bashrc/~/.profile),它的环境来自 /etc/environment。所以"终端能跑、cron 不跑"几乎都是环境差异——尤其是 ~/.bashrc 里配的 PATH、别名、变量。
实测(cron 把 PATH 打进日志):
* * * * * echo "PATH=$PATH date=$(date +%s)" >> /tmp/cron_test.log
实测输出:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
这条 PATH 与 /etc/environment 完全一致——说明cron 走的是 PAM 读 /etc/environment 的路径,而不是 shell rc。若 /etc/environment 没定义 PATH,才会退化为系统默认的 /usr/bin:/bin。
注意:网上常说"cron 的 PATH 只有
/usr/bin:/bin"——在本机实测不成立。真正稳定的结论是"cron 不读 shell 配置",而不是"PATH 一定很窄"。
2. crontab 的五个字段
* * * * * command
│ │ │ │ └── 星期(0-7,0/7=周日)
│ │ │ └───── 月(1-12)
│ │ └──────── 日(1-31)
│ └─────────── 时(0-23)
└────────────── 分(0-59)
| 需求 | 写法 |
|---|---|
| 每 5 分钟 | */5 * * * * |
| 每天 3 点 | 0 3 * * * |
| 工作日 9 点 | 0 9 * * 1-5 |
| 每月 1 号 | 0 0 1 * * |
3. 不执行的六个原因(E-S15-013)
| # | 原因 | 验证/解法 |
|---|---|---|
| 1 | PATH 不含命令(cron 不读 ~/.bashrc) |
用绝对路径(/usr/bin/node),或在 crontab 顶部写 PATH=... |
| 2 | 脚本无执行权限 | chmod +x,或用 sh script.sh |
| 3 | 工作目录不是你以为的 | 脚本里 cd /path 或全用绝对路径 |
| 4 | 环境变量缺失(JAVA_HOME 等) |
在 crontab 顶部写 VAR=value |
| 5 | 没换行/格式错 | crontab 最后一行要有换行 |
| 6 | cron 服务没跑 | systemctl status cron |
排查第一步:把命令的输出重定向到文件——>> /tmp/x.log 2>&1,否则错误信息会被 cron 丢掉(发邮件但多数环境没配)。
4. 开机自启的三种方式
| 方式 | 适用 | 说明 |
|---|---|---|
| systemd service | 长期服务 | 推荐(能重启、能看日志) |
@reboot(cron) |
一次性任务 | 简单但不自愈 |
/etc/rc.local |
旧系统 | 现代发行版常默认不启用 |
systemd 最小 unit:
[Unit]
Description=my app
After=network.target
[Service]
ExecStart=/usr/bin/node /opt/app/server.js
Restart=always
User=app
[Install]
WantedBy=multi-user.target
systemctl daemon-reload && systemctl enable --now myapp
判据:"进程挂了要自动拉起吗?" 要 → systemd(Restart=always);只是定时跑一次 → cron。
5. 五个误区
| 误区 | 真相 |
|---|---|
| "终端能跑 cron 就能跑" | PATH/环境不同 |
| "cron 会记录错误" | 默认丢弃 |
"@reboot 能代替 systemd" |
不自愈、无日志 |
"cron 的 % 可以直接写" |
需转义 \% |
| "改了 crontab 立即生效" | 一般会重载,但格式错会静默失败 |
6. 自检
- cron 的五个字段顺序?
- "终端能跑、cron 不跑"的六个原因?
- 排查第一步为什么要重定向输出?
- systemd 与 cron 的分工?
- cron 里
%要注意什么?
7. 下一篇
S15-J03 · 抓包与网络排障
定时讲完,下一篇讲"连不上时怎么一层层查"。
本篇属于系列《S15 · Linux 与运维》。旧文来源:A-1301/1331;扩展点 E-S15-013。crontab 行为为 Ubuntu 24.04 实测。