根本原因是cron使用极简环境(PATH默认仅/usr/bin:/bin),不加载~/.bashrc等配置;解决方法是在crontab开头显式设置PATH、SHELL、HOME变量,所有命令和路径用绝对路径,并通过env日志对比验证。

脚本手动能跑,但 crontab 里报 command not found,根本原因是 cron 启动时用的是极简环境:PATH 默认只有 /usr/bin:/bin,不读 ~/.bashrc、~/.profile,也不自动加载你装的工具路径(比如 composer、python3、node、jq 等)。解决的关键不是“猜哪里错了”,而是显式补全环境。
在 crontab 文件开头统一设置 PATH、SHELL、HOME
这是最稳、最推荐的做法。运行 crontab -e,在第一行(任何任务之前)添加:
-
PATH:列出所有命令实际所在的目录,用冒号分隔。例如:
PATH=/usr/local/bin:/usr/bin:/bin:/home/youruser/.local/bin:/home/youruser/.config/composer/vendor/bin:/opt/node/bin
✅ 用which python3、which composer、which node确认真实路径;
❌ 不要写$PATH或空格(PATH = ...会失效)。 -
SHELL:固定为
/bin/bash,避免某些系统默认用/bin/sh导致语法错误:SHELL=/bin/bash -
HOME:设成你的家目录,确保
~展开、配置文件读取正常:HOME=/home/youruser
所有命令和路径必须用绝对路径
别依赖当前工作目录或 shell 别名:
- ❌ 错误写法:
python3 script.py、./backup.sh、composer install - ✅ 正确写法:
/usr/bin/python3 /opt/myapp/script.py、/bin/bash /opt/myapp/backup.sh、/usr/bin/php /home/youruser/.local/bin/composer install - PHP/Python 脚本内部也别用相对路径,改用:
PHP:__DIR__ . '/config.php';
Python:os.chdir('/opt/myapp')或Path(__file__).parent
验证 cron 实际环境,别靠猜测
加一条测试任务,把真实运行环境打出来:
- 在 crontab 中添加:
* * * * * env > /tmp/cron_env.log 2>&1 - 等 1 分钟后执行:
cat /tmp/cron_env.log | grep -E '^(PATH|HOME|SHELL)' - 再在终端执行
env | grep -E '^(PATH|HOME|SHELL)'对比差异,缺什么就补什么
单任务临时补救(适合快速修复)
如果不想改全局配置,可在某条任务里直接指定:
- 用
env传入 PATH:0 3 * * * env PATH="/usr/bin:/bin:/home/youruser/.local/bin" /usr/bin/python3 /home/youruser/script.py - 或更彻底——全部用绝对路径:
0 3 * * * cd /opt/myapp && /usr/bin/python3 /opt/myapp/main.py >> /var/log/myjob.log 2>&1


















