元数据
| id | crontab-env-path | 收录 | 2026-08-29 |
|---|---|---|---|
| 问题域 | 编码代理与终端 | 主题分组 | 调度与自动化 |
| 适用工具 | cron · 外部工具 | ||
症状
crontab 定时任务跑起来后报找不到命令 / 环境不对:
```
# 任务里调用 node(nvm 装的)、conda、或自定义脚本,日志只有一行:
/bin/sh: 1: demo-node: not found
```
特征:交互终端里命令明明能用(`which node` 有结果),但 cron 任务执行时 `command not found`;
或者任务能跑但读不到环境变量(NVM_DIR、CONDA_PREFIX、自定义 export);
cron 日志里只有一行 `/bin/sh: N: xxx: not found`,没有更多线索;
常见于:nvm/conda/pyenv 装的工具、`~/.bashrc` 里 export 的变量、需要登录 shell 才有的环境。
原因
cron 执行任务的 shell 与我们交互终端的环境完全不同:
- cron 用 `/bin/sh` 执行命令,**不加载** `~/.bashrc`、`~/.profile`、`/etc/profile`——nvm/conda/pyenv 的初始化(它们都写在 `~/.bashrc` 里)全部缺失;
- 任务的 PATH 由 cron 守护进程决定:传统 SysV cron 默认 `/usr/bin:/bin`,不含 `/usr/local/bin`,更不含 nvm/conda 的自定义目录;
- 反常识实测(本机 Ubuntu 26.04):systemd 以 `cron -f -P` 启动时,任务继承的是 systemd 的 PATH
(`/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin`)——`/usr/local/bin` 其实可用,
真正中招的是 `~/.nvm/versions/.../bin`、conda 环境目录这类"只在 .bashrc 里加"的路径和变量;
- 别名(alias)也一样:cron 环境里 alias 不生效。
解法
1. **先确认任务的环境**:临时把 `printenv > /tmp/cron-env.txt 2>&1` 放进任务,跑一次看 PATH 和变量——
比猜快得多;或直接看 cron 守护进程环境:`tr '\0' '\n' < /proc/$(pgrep -x cron)/environ | grep PATH`。
2. **修复 A:crontab 顶部声明 PATH**(最常用):
`PATH=~/.nvm/versions/node/v20/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`
放在 crontab 第一行,任务就能用相对命令名。
3. **修复 B:任务里用绝对路径**:`~/.nvm/versions/node/v20/bin/node /path/script.js`——不依赖 PATH,最稳。
4. **修复 C:任务内先加载环境**:`* * * * * . "$HOME/.bashrc" && mycmd`(注意 .bashrc 通常有非交互守卫,
更稳的是把需要的东西写进一个独立 env 文件,任务里 `. /path/env.sh && mycmd`)。
5. **调试技巧**:cron 任务输出重定向到日志(`>> /tmp/job.log 2>&1`),失败时第一行 `/bin/sh: N: xxx: not found`
里的 `xxx` 就是要补路径/变量的那个命令;修好后重跑一次并确认日志出现正常输出。
验证证据
- 本地实测(2026-08-29,Ubuntu 26.04 LTS,systemd cron,任务输出重定向捕获):
- 环境基线:`cron -f -P`(systemd cron.service)→ cron 进程 PATH 实测为
`/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin`;
- 模拟 nvm/conda:命令 `demo-node` 只装在 `~/nvmbin/`(不在上述 PATH);
- 失败版:crontab 不声明 PATH,任务 `* * * * * demo-node >> /tmp/cron-debug.log 2>&1` →
下一次刻度后日志为 `/bin/sh: 1: demo-node: not found`(与 [SO #21775749](https://stackoverflow.com/q/21775749) 同款现象);
- 修复 A:crontab 顶部 `PATH=$HOME/nvmbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` →
任务正常执行,日志输出 `NODE-OK <时间>`;
- 修复 B:任务改为 `~/nvmbin/demo-node` 绝对路径 → 同样正常执行;
- 清理:测试 crontab 已删除、cron 已停止、临时文件已删除(宿主 root crontab 无残留)。
- 素材:[SO #21775749](https://stackoverflow.com/q/21775749)《Command not found even crontab PATH is set》(老教程普遍只讲"cron 默认 PATH=/usr/bin:/bin",
本条目补上了 systemd 场景的实测修正)。
- 实测复现日志(2026-08-29)
来源与证据
素材来源:https://stackoverflow.com/questions/21775749/command-not-found-even-crontab-path-is-set
验证证据:Evidence details kept locally (2026-08-29)