2015-02-18 94 views
0

我试图用subprocess.check_call()在不同的Python virtualenvs中启动一个命令。如何使用subprocess.Popen()在virtualenv中运行`pip`?

要激活的virtualenv(在Python 2/3不可知的方式),我简单的路径添加到我的virtualenv bin(或Scripts 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第一。

什么能解释这种奇怪的行为?

回答

2

PATH不是第一个在Windows上使用Popen()寻找可执行文件的地方。它可以使用与父级python.exe进程相同的目录中的pip.exe。外壳(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()) 
+0

嗯,在我的情况下,它是指定命令行执行用户(和我的'pip'例子恰好是命令的一个失败没有'外壳= True')所以这不是我的电话预先完整的路径pip。我猜想使用'shell = True'是合理的,因为我试图通过在终端中运行命令来模拟用户将获得的行为。谢谢你的解释,但是这让我疯狂。 – ereOn 2015-02-18 14:51:33

+0

而不是使用'pip.exe'不能os.system('哪个pip')将是最好的? – ahujamoh 2015-09-21 05:57:53

+0

@ahujamoh:'哪个pip'可能会在未修改的环境中返回一个错误的'pip',否则可以使用'call([sys.executable,'-m','pip',..])''。如果你有一个明确的virtualenv路径;没有理由使用'which'(即使忽略其他原因来避免“which”)。 – jfs 2015-09-21 06:33:36

相关问题