未操作文件却触发FileNotFoundError的Python虚拟环境问题求助
问题解决方法
错误原因
source 是Shell的内置命令,并非独立可执行文件。subprocess.run() 默认不会启动Shell,系统会把它当作普通文件查找,因此找不到对应文件触发 FileNotFoundError。而 os.system() 会默认启动Shell,所以能正常执行该命令。
解决方案
1. 让subprocess启动Shell执行命令
修改 run() 的调用代码,添加 shell=True 参数,同时将命令调整为字符串格式:
from subprocess import run, PIPE def fun(): venv = run(("python", "-m", "venv", "env"), stdout=PIPE, stderr=PIPE) if venv.returncode == 0: # 启动Shell执行source命令 activate = run("source env/bin/activate", stdout=PIPE, stderr=PIPE, shell=True) if activate.returncode == 0: print("虚拟环境创建完成!(注:子Shell激活不影响当前Python进程)") else: print(activate.stderr.decode()) else: print(venv.stderr.decode()) fun()
注意:
source激活虚拟环境仅在子Shell中生效,Python主进程不会继承该环境变量。如果要在脚本后续逻辑中使用虚拟环境,直接调用虚拟环境内的Python解释器即可,无需激活。
2. 脚本内使用虚拟环境的正确方式
如果你的目标是在脚本中执行依赖虚拟环境的操作,无需激活环境,直接调用虚拟环境的Python解释器运行命令:
from subprocess import run, PIPE def fun(): venv = run(("python", "-m", "venv", "env"), stdout=PIPE, stderr=PIPE) if venv.returncode == 0: # 直接用虚拟环境的Python安装依赖或执行代码 install_deps = run(("env/bin/python", "-m", "pip", "install", "requests"), stdout=PIPE, stderr=PIPE) if install_deps.returncode == 0: print("虚拟环境创建成功,依赖已安装!") else: print(install_deps.stderr.decode()) else: print(venv.stderr.decode()) fun()
补充说明
- 使用
shell=True时,若命令包含不可信用户输入需警惕注入风险,你的场景不存在该问题。 stderr和stdout返回的是字节流,需用.decode()转为字符串才能正常显示。
内容的提问来源于stack exchange,提问作者Sihle Josias Makhanya
相关产品推荐
相关产品推荐

