为什么 apt-get 安装比指定包支持的更新的依赖项

Jas*_*ome 8 package-management apt

我遇到了一个问题,一个特定版本的包需要另一个同样是特定版本的包,但 Apt-Get 选择了更新版本的依赖项,然后失败。

我在 Puppet Lab 的 MCollective 和 Nginx Mainline PPA 以及可能的其他软件包中遇到过这种情况,所以我的问题是关于 Apt-Get 依赖项解析的一般方法,但我将使用 Nginx 作为我的示例。

我有一个包镜像(使用 Aptly 构建),其中包含 nginx-full 包的 v1.7.5 及其所有依赖项,以及较新的 v1.7.6 包及其所有依赖项。

如果我执行,apt-get install nginx-full=1.7.5-1+trusty1则安装失败并显示以下消息:

The following packages have unmet dependencies:
 nginx-full : Depends: nginx-common (= 1.7.5-1+trusty1) but 1.7.6-1+trusty1 is to be installed
Run Code Online (Sandbox Code Playgroud)

但是,如果我执行apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1然后安装成功。

当我在镜像上同时拥有 nginx-common 包的 1.7.5 和 1.7.6 版本并且 nginx-full 包明确指出它需要 1.7.5 的 nginx-common 时,nginx-full 是我请求的包,为什么apt-get还是选择了不兼容的1.7.6版本的nginx-common?

这是dpkg -s nginx-full安装 1.7.5 后的输出,显示了确切的版本依赖性约束:

Version: 1.7.5-1+trusty1
Depends: nginx-common (= 1.7.5-1+trusty1), libc6 (>= 2.14), ...
Run Code Online (Sandbox Code Playgroud)

在这种情况下,所需的精确版本链很短,因此解决方法很容易,但对我来说至少有两个问题:

  1. 其他包有更长的依赖链,发现这些依赖链很乏味,然后附加到 apt-get 命令行。
  2. 在更新版本的依赖项发布到包镜像之前,很容易不知道即将发生的问题。

我无法理解的是为什么依赖项解析显然忽略了对指定包的确切版本约束。更重要的是,我想知道如何让 Apt-Get 遵守约束,而不必手动将包元数据复制到我的 apt-get 参数上。

Tho*_*ard 8

您遇到的是apt/apt-get不如您想象的那么聪明的问题。

当尝试降级您的软件包或安装比存储库作为最新候选版本更旧的软件包版本时,会发生此问题(关于您的apt优先级固定和其他有关存储库优先级的策略)。当你降级你的包时,你实际上必须为每个单独的依赖项指定你要降级到哪个版本,或者在这种情况下你实际想要安装哪个特定版本。

nginx包的情况下, wherenginx-fullnginx-common相互依赖,您必须明确告诉 apt 安装指定版本的每个包。这是因为1.7.6-1+trusty11.7.5-1+trusty1版本号取代。因此,您必须明确说“仅安装此特定版本的包”,因为存在被取代的版本,即apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1

与您的问题无关,但是当您从apt固定优先级低于另一个版本的存储库安装时也会发生这种情况,在这种情况下,您必须手动指定要安装的版本和/或源,即sudo apt-get install nginx-full/trusty-proposed nginx-common/trusty-proposed作为尝试从建议的存储库安装包和依赖项的主要示例,其apt优先级远低于PPA 或主存储库。