2015-02-18 65 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