我正在从requirements.txt安装包

pip install -r requirements.txt

requirements.txt文件如下:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

LXML是唯一一个安装失败的包,这会导致一切失败(正如larsks在评论中指出的那样,这是预期的结果)。但是,在lxml失败之后,pip仍然运行并下载其余的包。

根据我的理解,如果requirements.txt中列出的任何一个包安装失败,pip install -r requirements.txt命令将失败。

当运行pip install -r requirements.txt时,是否有任何参数可以传递给它,告诉它安装它可以安装的包,跳过它不能安装的包,或者在它看到某些失败时立即退出?


当前回答

xargs解决方案可以工作,但可能存在可移植性问题(BSD/GNU),并且/或者如果您的需求文件中有注释或空行,那么会很麻烦。

至于需要这种行为的用例,我使用了两个单独的需求文件,一个只列出了需要始终安装的核心依赖项,另一个文件列出了在90%的情况下对大多数用例不需要的非核心依赖项。这相当于debian包的推荐部分。

我使用以下shell脚本(需要sed)来安装可选的依赖项:

#!/bin/sh

while read dependency; do
    dependency_stripped="$(echo "${dependency}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
    # Skip comments
    if [[ $dependency_stripped == \#* ]]; then
        continue
    # Skip blank lines
    elif [ -z "$dependency_stripped" ]; then
        continue
    else
        if pip install "$dependency_stripped"; then
            echo "$dependency_stripped is installed"
        else
            echo "Could not install $dependency_stripped, skipping"
        fi
    fi
done < recommends.txt

其他回答

对于使用PowerShell的Windows:

foreach($line in Get-Content requirements.txt) {
    if(!($line.StartsWith('#'))){
        pip install $line
    }
}

另一种选择是使用pip install—dry-run来获得需要安装的包的列表,然后继续尝试并删除不能工作的包。

基于@MZD的回答,这里有一个解决方案,可以过滤掉所有以注释符号#开头的文本

cat requirements.txt | grep -Eo '(^[^#]+)' | xargs -n 1 pip install

谢谢你,艾蒂安·普罗通。

但是,升级到pip 18后,pip包主要不会向公众公开。因此,您可能需要像这样更改代码。

 # This code install line by line a list of pip package 
 import sys
 from pip._internal import main as pip_main

 def install(package):
    pip_main(['install', package])

 if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)

Windows:

PIP版本>=18

import sys
from pip._internal import main as pip_main

def install(package):
    pip_main(['install', package])

if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)

PIP版本<18

import sys
import pip

def install(package):
    pip.main(['install', package])

if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)