【问题标题】:How to run `pip` in a virtualenv with subprocess.check_call()?如何使用 subprocess.check_call() 在 vi​​rtualenv 中运行`pip`?
【发布时间】:2015-02-18 00:51:17
【问题描述】:

我正在尝试使用 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的路径。

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

【问题讨论】:

    标签: python windows subprocess virtualenv


    【解决方案1】:

    PATH 不是 Windows 上 Popen() 使用的 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())
    

    【讨论】:

    • 好吧,在我的情况下,它是指定要执行的命令行的用户(而我的 pip 示例恰好是在没有 shell=True 的情况下失败的命令之一)所以这不是我的电话将完整路径添加到 pip。我想使用shell=True 是有道理的,因为我试图通过在终端中运行命令来模拟用户会得到的行为。不过感谢您的解释,这让我发疯了。
    • 而不是使用 'pip.exe' 不能 os.system('which pip') 将是最好的?
    • @ahujamoh: which pip 可能会在未修改的环境中返回错误的pip,否则可以使用call([sys.executable, '-m', 'pip', ..])。如果您有指向 virtualenv 的显式路径;没有理由使用which(即使忽略其他原因来避免which)。
    猜你喜欢
    • 2018-05-15
    • 2014-06-20
    • 1970-01-01
    • 2017-03-26
    • 2013-01-19
    • 2015-10-08
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多