在Debian 12上敲python3 -m venv .venv,屏幕直接甩出一段红字:The virtual environment was not created successfully because ensurepip is not available。装好之后换到Windows上建,环境建得出来,激活时又报「无法加载文件Activate.ps1,因为在此系统上禁止运行脚本」。这两类报错每个月都能碰上几次,背后的原因其实是固定的几件小事。
先看报错停在哪个阶段
venv相关的报错大致分三处:建不出来、建出来激活不了、激活了却不生效。报错原文决定后面走哪条路,把原文复制出来对着看,比凭感觉试参数快。
# 创建阶段失败 The virtual environment was not created successfully because ensurepip is not available. On Debian/Ubuntu systems, you need to install the python3-venv package # 激活阶段失败(Windows PowerShell) 无法加载文件 D:\proj\venv\Scripts\Activate.ps1,因为在此系统上禁止运行脚本。 # 激活了却没生效 $ which python /usr/bin/python3
Debian系缺venv模块
Python 3.10、3.11、3.12、3.13,这几个版本在Debian系发行版上都被拆过包,标准库里的venv被单独拆成python3-venv,装系统时不一定带上。Debian 11、12、13,以及Ubuntu 22.04、24.04,都是这套拆法,指定版本的包名要跟解释器的小版本对上,装python3-venv通常就够了,遇到多版本共存时直接装python3.11-venv、python3.12-venv这种带版本号的包更稳。
python3 -V sudo apt update sudo apt install -y python3-venv python3-full # 多版本共存时按实际版本装 sudo apt install -y python3.11-venv # 确认模块确实可用了 python3 -c "import ensurepip; print(ensurepip.version())"
Rocky Linux、AlmaLinux这类RHEL系默认就带venv,碰到这条报错的几乎都是Debian系,所以排查时先看发行版能省一半时间。
系统Python被标记成外部管理
另一条常见报错是pip install时出现error: externally-managed-environment,提示用apt装或者建虚拟环境。这是PEP 668的保护,发行版在/usr/lib/python3.11/EXTERNALLY-MANAGED放了个标记文件,pip读到就拒绝往系统Python里写。Ubuntu 22.10、Debian 12之后的默认行为都是这样,先看一眼标记在不在:
ls /usr/lib/python3*/EXTERNALLY-MANAGED
正解就是建venv,不是加--break-system-packages。见过有人为了省事加了那个参数,几个月后apt升级时报一堆依赖冲突,排查起来比当初建环境麻烦十倍。装命令行工具(black、httpie、poetry这类)走pipx更合适,它给每个工具单独建一个环境。真需要给系统脚本用到的库,就装apt里的python3-requests、python3-numpy这种发行版包。
PowerShell的执行策略挡住激活脚本
Windows下建出来的venv,Scripts目录里同时有activate.bat、Activate.ps1和activate三个脚本。cmd里直接跑activate.bat就行,PowerShell里跑Activate.ps1才会触发执行策略。PowerShell 5.1、7.4、7.5,默认策略都是Restricted,禁跑任何脚本。
Get-ExecutionPolicy -List # 只对当前用户放开,影响面最小 Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
不想动策略的话有三条路:用cmd跑venv\Scripts\activate.bat;Git Bash里source venv/Scripts/activate;或者干脆不激活,直接用venv\Scripts\python.exe -m pip install和venv\Scripts\python.exe app.py,效果一样。写CI脚本时一直用最后这种,省掉激活这一步。
venv改名或挪位置就废了
这个坑踩过两次。venv不是可迁移的目录,Scripts/activate和bin/activate里把VIRTUAL_ENV写成了绝对路径,pyvenv.cfg里的home也是。目录一改名,激活后pip还是指向外面。
处理办法就是删掉重建,几十秒的事。virtualenv虽然有--relocatable,但官方一直标着实验性质,venv本身没有这个选项,别指望它。
确认到底进没进环境
激活后提示符前面多了(venv)不代表一定生效,尤其shell有路径缓存的时候。Linux上改完先跑hash -r,或者开个新终端。判断依据看这个:
python -c "import sys; print(sys.prefix); print(sys.base_prefix)" which python # Linux/macOS where python # Windows
sys.prefix与sys.base_prefix打印出来是同一个路径,说明没进环境;前者指向venv目录才算对。2026年这会儿在Python 3.12、3.13上这个判断依然最可靠,比看提示符强。
几个用得上的参数
--system-site-packages适合要用系统里那些装起来很重的包(PyQt5、opencv这类)的场景,省得在venv里重新编译一遍。--without-pip建出不带pip的干净环境,配合外部pip用。python -m venv --upgrade在解释器小版本升过之后重建软链接。这几个参数可以叠:
python3 -m venv --system-site-packages .venv python3 -m venv --without-pip .venv python3 -m venv --upgrade .venv
建完顺手把pip升一下,venv自带的pip往往是打包时的版本,装新版包时偶发解析问题:
python -m pip install --upgrade pip pip -V
编辑器里选对解释器
VS Code按Ctrl+Shift+P,输Python: Select Interpreter,选.venv/bin/python那一项,之后新开的集成终端会自动激活。PyCharm新建项目时直接勾上虚拟环境更省事。项目根目录记得把.venv写进.gitignore,当初漏过一次,一次提交多出几千个文件。
数据截至2026年9月,在Debian 13与Ubuntu 24.04上验证过上述命令。