根本原因是cron使用极简/bin/sh环境,不加载~/.bashrc、venv或conda,path仅限/usr/bin:/bin,导致python3、pip及模块路径均不可见;解决方法是显式设置path、用绝对路径调用解释器、强制cd到项目目录并重定向日志。

根本原因不是代码问题,而是 cron 启动时压根没加载你的 Python 环境。 它用的是极简的 /bin/sh,PATH 被砍到只剩 /usr/bin:/bin,~/.bashrc、venv、conda 全部失效——你手动运行时依赖的那些路径和变量,在 cron 里一个都不存在。
crontab 默认 PATH 太窄,找不到 python3 或 pip 包
cron 不读 ~/.bashrc,也不继承你的终端 PATH。它启动时只认 /usr/bin:/bin,所以:
-
which python3在终端输出/usr/local/bin/python3,但 cron 根本看不到这个路径 -
pip install requests装到了用户级或虚拟环境里,而 cron 的 Python 解释器是系统默认的/usr/bin/python3,自然报ModuleNotFoundError - 即使你写了
#!/usr/bin/env python3,env也只会按 cron 自己的 PATH 去找python3,结果还是落到系统 Python 上
解决方法不是“改脚本”,而是让 cron 明确知道该用哪个解释器和路径:
- 在 crontab 文件顶部加一行:
PATH=/usr/local/bin:/usr/bin:/bin:/home/youruser/.local/bin(把which python3和pip show requests显示的路径都列进去) - 或者直接在定时任务里写死解释器:
* * * * * /opt/python38/bin/python3.8 /path/to/script.py
虚拟环境或 conda 环境在 cron 中完全不生效
source activate myenv 或 conda activate myenv 在 cron 里无效——因为 cron 不启动交互式 shell,source 命令根本不被识别,PATH 也不会被重写。
- conda 用户必须用完整解释器路径:
/path/to/miniconda3/envs/myenv/bin/python - venv 用户同理:
/path/to/project/venv/bin/python - 别在 crontab 里写
source ~/.bashrc && python script.py——/bin/sh不支持source,会直接报错command not found
验证方式:在 crontab 里加一行测试命令,看实际环境长什么样:
* * * * * /usr/bin/env > /tmp/cron_env.log 2>&1
对比你手动执行 env 的输出,就能看出缺了哪些关键变量(比如 PYTHONPATH、CONDA_DEFAULT_ENV)。
脚本里用了相对路径,cron 执行时 pwd 是 $HOME
你在终端 cd 到项目目录再运行 python main.py,脚本里 open("config.json") 没问题;但 cron 默认工作目录是用户 home(/root 或 /home/xxx),config.json 就找不到了。
- 所有文件操作必须用绝对路径:
/path/to/project/config.json - 或者在脚本开头强制切换目录:
import os; os.chdir("/path/to/project") - 更稳妥的做法是在 crontab 里显式
cd:* * * * * cd /path/to/project && /path/to/venv/bin/python main.py
注意:&& 是关键,确保只有 cd 成功后才执行 python,避免静默失败。
最容易被忽略的一点:cron 日志默认不输出错误,你以为任务没跑,其实它跑失败了但你根本看不到报错。务必在每条定时任务末尾加上 > /tmp/job.log 2>&1,否则排查等于盲人摸象。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











