我正在尝试使用subprocess.check_call()
在不同的Python virtualenvs中启动命令。
要激活virtualenv(以Python 2/3不可知的方式),我只需将我的virtualenv bin
(或Windows下的Scripts
)的路径追加到PATH
,然后使用此修改后的环境调用subprocess.check_call()
。像这样:
environment = os.environ.copy()
environment['PATH'] = os.pathsep.join([bin_path, environment['PATH']])
subprocess.check_call("pip install -r dev_requirements.txt", env=environment)
但是,我注意到pip
安装了系统Python站点包中的所有内容。如果我更改了check_call()
:
subprocess.check_call("pip install -r dev_requirements.txt", env=environment, shell=True)
然后突然pip
按照预期在virtualenv中运行。
困扰我的是,在两种情况下运行where pip
首先为我提供了通往virtualenv pip
的路径。
什么可以解释这种奇怪的行为?
答案 0 :(得分:2)
PATH不是CreateProcess()
在Windows上Popen()
查找可执行文件的第一个地方。它可以使用与父pip.exe
进程相同的目录中的python.exe
。 shell(cmd.exe
)使用不同的规则。请参阅Popen with conflicting executable/path。
避免依赖;使用pip
的显式完整路径。在这种情况下,您无需更改环境:
import os
from subprocess import check_call
check_call([os.path.join(bin_path, 'pip.exe')] +
'install -r dev_requirements.txt'.split())