crontab执行时环境极简,仅含path=/usr/bin:/bin,不加载bashrc等配置,易致命令或模块找不到;应写包装脚本显式加载环境并用绝对路径调用。

Linux 定时任务(crontab)执行时的环境变量,和你手动登录终端后执行命令的环境是不同的——它默认只加载极简的环境(通常只有 PATH=/usr/bin:/bin),没有你的 ~/.bashrc、~/.profile 或系统级的 /etc/profile,所以经常出现“命令找不到”“Python 模块导入失败”“conda 环境不生效”等问题。
crontab 默认不加载用户 shell 配置文件
这是最根本的原因。cron 启动任务时使用的是 /bin/sh(不是你的默认 shell),且不会主动 source 任何配置文件。即使你在 crontab -e 里写了 source ~/.bashrc,也大概率无效,因为 /bin/sh 不支持 source(应改用 .),而且 ~ 在 cron 中可能未正确展开。
- 不要依赖
source ~/.bashrc或export PATH=...写在 crontab 行首——容易失效或语法错误 - 避免用
~,统一用绝对路径,比如/home/username/.bashrc - 测试时可用
sh -c 'echo $PATH'模拟 cron 环境
推荐做法:用包装脚本统一管理环境
写一个可执行的 shell 脚本,在开头显式加载所需环境,再执行实际命令。这样逻辑清晰、便于调试、也符合 cron 的运行机制。
- 新建脚本如
/home/user/run_job.sh,开头加上:
#!/bin/bash
. /home/user/.bashrc # 注意用点号,且路径必须绝对
cd /home/user/project
python3 main.py - 给脚本加执行权限:
chmod +x /home/user/run_job.sh - crontab 中直接调用:
0 2 * * * /home/user/run_job.sh - 脚本内可重定向输出,方便查错:
/home/user/run_job.sh >> /home/user/job.log 2>&1
快速验证 cron 环境变量的方法
临时加一条 cron 记录,把当前环境完整导出,就能看清它到底用了什么:
- 在 crontab 中添加:
* * * * * env > /tmp/cron_env.txt 2>&1(每分钟执行一次) - 等一分钟后查看
/tmp/cron_env.txt,重点关注PATH、SHELL、HOME、USER - 对比你手动执行
env的结果,差异一目了然 - 确认后再删掉这条测试任务
特殊场景:conda / virtualenv / 自定义 PATH
如果你的任务依赖 conda 环境或虚拟环境,不能只靠 source ~/.bashrc,因为 conda 初始化代码可能没运行,或者 conda activate 在非交互 shell 中行为异常。
- 对于 conda:在脚本中先初始化 conda(用
conda init bash生成的初始化代码片段),或直接调用conda run -n myenv python script.py - 对于 Python virtualenv:用绝对路径的解释器更可靠,例如
/home/user/venv/bin/python main.py - 如果必须扩展 PATH,建议在脚本中写:
export PATH="/opt/mytools/bin:$PATH",而不是指望 cron 读取 profile










