编码代理与终端 · 收录于 2026-08-29 · 适用 1 工具 ✓ 实测验证

crontab 任务报 command not found / 环境变量缺失(nvm、conda 装的东西跑不了)

已验证 2026-08-29crontab 报 command not found 是 cron 环境不继承 shell PATH——crontab 顶部显式声明完整 PATH 后重载。

快速修复

# 一键:crontab 顶部声明完整 PATH(最常用修复)
# 第一行:PATH=~/.nvm/versions/node/v20/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

按你的实际路径写;改完 crontab 文件 重载。

你会遇到什么

crontab 定时任务跑起来后报找不到命令:交互终端里 which node 明明有结果,cron 任务却只留一行 /bin/sh: 1: demo-node: not found。或者任务能跑但读不到环境变量(NVM_DIR、CONDA_PREFIX、自定义 export)。日志只有一行,没更多线索。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

cron 执行任务的 shell 与我们交互终端的环境完全不同:

差异点说明
不加载 shell 配置cron 用 /bin/sh 执行,~/.bashrc、~/.profile、/etc/profile 全不加载——nvm/conda/pyenv 的初始化全部缺失
PATH 由 cron 守护进程决定传统 SysV cron 默认 /usr/bin:/bin,不含自定义目录
systemd 场景(实测)systemd 以 cron -f -P 启动时 PATH 含 /usr/local/bin,真正中招的是 ~/.nvm/versions/.../bin、conda 环境目录这类"只在 .bashrc 里加"的路径和变量
aliascron 环境里 alias 不生效

cron 的执行环境与交互终端是两套环境:cron 用 /bin/sh 执行任务,不加载 ~/.bashrc/~/.profile//etc/profile——nvm/conda/pyenv 的初始化(只在 rc 里 export)全部缺失;

PATH 由 cron 守护进程决定(传统 SysV cron 默认 /usr/bin:/bin,systemd 启动的 cron 稍宽但同样不含「只在 .bashrc 里加的路径」)。

alias 在非交互 shell 里本来就不生效。

确定性推论:cron 里「命令找不到/环境变量空」≠ 系统坏了,是「该命令不在 cron 的 PATH 里」;

三条正路——脚本开头显式 export PATH=... 或写命令绝对路径(/usr/bin/python3)、把需要的初始化写进脚本本身(source ~/.bashrc 在 cron 里也可用但要看具体 shell)、或 cron 行里写 bash -lc 模拟登录环境(最接近终端,但引入终端环境的不确定性);

调试用 * * * * * cmd >> /tmp/cron.log 2>&1 看实际环境;

判断路径:手动能跑、cron 不能 = 环境差异,不是脚本逻辑。

一步步来

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=... 放在 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. 调试技巧 — 必做

任务输出重定向到日志(>> /tmp/job.log 2>&1);失败时第一行里的 xxx 就是要补路径/变量的那个命令。

怎么确认修好了

任务正常执行(实测输出形态):

crontab 声明 PATH 后 → 任务日志输出 NODE-OK <时间>(实测)
绝对路径版 → 同样正常执行(实测)

其它环境的表现

环境说明
传统 SysV cron默认 PATH=/usr/bin:/bin,顶部声明 PATH
systemd cronPATH 含 /usr/local/bin(实测),nvm/conda 目录仍需显式声明
nvm/conda/pyenv初始化在 .bashrc,cron 不加载
aliascron 里不生效
调试printenv 进任务,或 /proc/<cron pid>/environ

症状

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。

  1. 修复 A:crontab 顶部声明 PATH(最常用):

PATH=~/.nvm/versions/node/v20/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 放在 crontab 第一行,任务就能用相对命令名。

  1. 修复 B:任务里用绝对路径:~/.nvm/versions/node/v20/bin/node /path/script.js——不依赖 PATH,最稳。
  2. 修复 C:任务内先加载环境:* * * * * . "$HOME/.bashrc" && mycmd(注意 .bashrc 通常有非交互守卫,

更稳的是把需要的东西写进一个独立 env 文件,任务里 . /path/env.sh && mycmd)。

  1. 调试技巧: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 同款现象);

  • 修复 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《Command not found even crontab PATH is set》(老教程普遍只讲"cron 默认 PATH=/usr/bin:/bin",

本条目补上了 systemd 场景的实测修正)。

  • 实测复现日志(2026-08-29)

适用工具 (1)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

cron · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 1 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://stackoverflow.com/questions/21775749/command-not-found-even-crontab-path-is-set

← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡