能力倾向搜索?狭窄与?和

能力倾向搜索?狭窄与?和

aptitude 搜索的?narrow和选项有什么区别??and例如,为什么aptitude search "?and(?installed,?origin(backports))"我的系统会返回结果,但aptitude search "?narrow(?installed,?origin(backports))"什么也不返回?

apt-cache policy请注意,在版本返回的包上运行?and表明安装的版本不是来自向后移植的,因此?narrow结果是正确的。但我之前遇到过类似的不直观的结果,?narrow在一些谷歌搜索后已通过使用解决了这些结果,但从未理解为什么。

答案1

简短回答

第一个命令

aptitude search '?and(?installed,?origin(backports))'

找到的包是已安装并有一个向后移植可用的,但向后移植不一定已安装。 (也许已安装向后移植,也许没有。)

相比之下,第二个命令

aptitude search '?narrow(?installed,?origin(backports))'

找到的包是已安装,以及当前安装的版本来自反向移植,即实际安装的反向移植。这是一个限制性更强的搜索,因为已安装向后移植是一个子集可用的向后移植。你可以这样想:

  • 所有套餐

    • 已安装的软件包

      • 具有可用向后移植的已安装软件包(第一个命令)

        • 安装的向后移植(第二个命令)

在您的系统上,第一个命令返回结果,但第二个命令不返回任何内容。这意味着您已经安装了具有可用反向移植的软件包,但显然当前没有安装这些反向移植。

长答案

这与能力之间的区别有关包裹并匹配封装版本。来自 文档

将模式与包匹配与将模式与该包的所有版本匹配之间存在微妙但重要的区别。当模式与包匹配时,它的每个术语都与包匹配,因此每个术语将匹配,如果任何包的版本匹配。相反,当模式与包的每个版本匹配时,如果模式的所有术语都与包的版本匹配,则模式将成功匹配。相同的包的版本。

例如:假设已安装该版本3.0-1的软件包,但该版本可用。然后搜索表达式与 aardvark 匹配,因为 与aardvark 的 version 匹配,而与 version 匹配。另一方面,此表达式并不与 的所有版本匹配,因为没有安装任何单个版本并且版本号也为。aardvark4.0-1?version(4\.0-1)?installed?version(4\.0-1)4.0-1?installed3.0-1aardvark4.0-1

文档 用于?and读取:

?and(pattern1, pattern2), pattern1 pattern2

匹配同时匹配两者的包模式1模式2

请注意,这匹配, 不是单一版本。所以这个查询:

aptitude search '?and(?installed, ?origin(backports))'

获取所有的列表软件包版本已安装的,然后是所有的列表软件包版本 与正则表达式匹配的原点backports,然后返回出现在两个列表中的。

另一方面,文档 用于?narrow读取:

?narrow(filter, pattern), ~S filter pattern

选择单个版本同时匹配过滤器和模式的包。

这就是为什么此查询仅显示其中的包单机安装版具有匹配的起源backports

aptitude search '?narrow(?installed, ?origin(backports))'

有一个相关的讨论 对于?any-version函数:

?any-version(pattern)

如果某个包的任何一个版本与所包含的模式匹配,则匹配该包。

注意:该术语与 密切相关?narrow。事实上, ?any-version(pattern1 pattern2)是完全一样的 ?narrow(pattern1, pattern2)

注意:准确地说,与任何其他模式一样,匹配的不是包,而是包的版本。对于aptitude search和其他用途,它没有太大区别,但aptitude versions只会显示匹配的版本,而不是任何版本匹配的包的所有版本。

通过运行aptitude versions代替aptitude search,我们发现这些查询都给出相同的结果:

aptitude versions '?and(?installed, ?origin(backports))'
aptitude versions '?installed?origin(backports)'
aptitude versions '?narrow(?installed, ?origin(backports))'

哇!如果您发现查询语言令人aptitude困惑(就像我一样),您可能更喜欢使用不同的方法,例如 Python 的绑定到libapt。您可以直接检查原始字符串,而不是匹配版本字符串,如下所示:

import apt

apt_cache = apt.Cache()

for pkg in apt_cache:
    if pkg.is_installed:
        for pkg_origin in pkg.installed.origins:
            if pkg_origin.origin == 'Debian Backports':
                print(pkg.name)

相关内容