如何使用 subprocess.check_call() 在 virtualenv 中 运行 `pip`?
How to run `pip` in a virtualenv with subprocess.check_call()?
我正在尝试使用 subprocess.check_call()
在不同的 Python virtualenvs 中启动命令。
要激活 virtualenv(以 Python 2/3 不可知的方式),我只需将路径附加到我的 virtualenv bin
(或 Scripts
under Windows ) 到 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
的路径。
如何解释这种奇怪的行为?
PATH 不是 Popen()
在 Windows 上使用的 CreateProcess()
查找可执行文件的第一个位置。它可以使用与父 python.exe
进程相同的目录中的 pip.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())
我正在尝试使用 subprocess.check_call()
在不同的 Python virtualenvs 中启动命令。
要激活 virtualenv(以 Python 2/3 不可知的方式),我只需将路径附加到我的 virtualenv bin
(或 Scripts
under Windows ) 到 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
的路径。
如何解释这种奇怪的行为?
PATH 不是 Popen()
在 Windows 上使用的 CreateProcess()
查找可执行文件的第一个位置。它可以使用与父 python.exe
进程相同的目录中的 pip.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())