如何检查虚拟包是否已安装?

4个回答

Apt 不会安装虚拟包,除非只有一个提供者。如果另一个软件包依赖于虚拟包,通常也会指定一个真实的软件包作为替代选择(例如,build-essential 依赖于 "libc6-dev | libc-dev" - 第二个是虚拟包)。
虚拟包不会被安装,因此无法检查它们的状态。您可以使用 apt-cache showpkg <pkg-name> 查看哪些软件包提供了虚拟包,然后检查这些软件包中是否有任何已安装的。

1请在输出中查看属性Reverse Provides - darkdragon
在我的情况下,这个答案对我很有帮助。我安装了一个建议安装另一个包的软件包。当我为此搜索信息时,我遇到了“无法选择' dovecot-common '软件包的版本,因为它是纯虚拟”的错误。通过使用这个答案,我能够找到我需要传递给apt-cache show的软件包名称(并进行安装)。 - apaderno

你可以使用grep-status(包名dctrl-tools,默认未安装)来查找所有安装的包提供某个虚拟包的情况。
$ grep-status -FProvides,Package -sPackage,Provides,Status awk 
Package: mawk
Provides: awk
Status: install ok installed

Package: gawk
Provides: awk
Status: install ok installed

这听起来很完美,我会在有空的时候试一试,并回复你。谢谢! - Noki

@FlorianDiesch的回答看起来很有趣,但我想要一个不需要任何默认安装软件的解决方案。
最终我使用了以下方法:
function check_packages_and_install_if_absent()
{
    for PACKAGENAME
    do
        if
            dpkg -l "$PACKAGENAME" | grep ^ii
        then
            echo "Package $PACKAGENAME is present"
            continue
        fi

        FOUND=""

        while read ACTUALPACKAGENAME
        do
            echo "$PACKAGENAME is a virtual package, that can be provided by $ACTUALPACKAGENAME"

            if
                dpkg -l "$ACTUALPACKAGENAME" | grep ^ii
            then
                echo "Actual package $ACTUALPACKAGENAME is present"
                FOUND=true
                break;
            fi

        done < <( apt-cache showpkg "${PACKAGENAME}" | sed -e '1,/^Reverse Provides: *$/ d' -e 's/ .*$//' | sort | uniq )

        # Using sed to print lines after match
        # https://stackoverflow.com/questions/32569032/sed-print-all-lines-after-match#answer-32569573

        if [[ "$FOUND" == "true" ]]
        then
            continue
        fi

        echo "Package $PACKAGENAME is absent, installing"
        sudo apt-get install -y "$PACKAGENAME"
    done
}

您可以使用常规和/或虚拟包名称列表来调用它:
function check_packages_and_install_if_absent foo bar baz

您可以使用以下命令查询已安装的软件包数据库中的packagename
dpkg -l packagename   

你可以列出packagename中的所有文件。
dpkg -L packagename

阅读man dpkg以获取更多信息,例如如何使用通配符。

如问题所述,这对虚拟包无效。 - Florian Diesch