如何强制安装被保留的软件包为“自动”?

简而言之

最近,在正常的软件升级过程中(即apt upgradeapt dist-upgrade),我开始收到类似以下的消息:

[...]
The following packages have been kept back:
  [...]
0 upgraded, 0 newly installed, 0 to remove and [...] not upgraded.


什么选择可以考虑?

注意:这与已经在此处提出的众多类似问题不是重复。您应该将我的问题视为this question的后续问题。

我在我的主要Ubuntu 22.04系统上遇到了与上述问题完全相同的问题。我更改了服务器,尝试手动安装指定的软件包,不知何故,问题在昨天解决了。今天,当我尝试安装任何新的更新时,收到了有32个软件包被保留的消息。

我有一个类似的22.04版本(虚拟)的Ubuntu安装,它现在已经完全更新,并且尚未出现此问题(具有类似的/etc/apt/sources.list文件)。因此,我尝试比较软件包。我以我主系统中被“保留”的软件包gir1.2-gstreamer-1.0为例,在我的主系统上运行了以下命令:

$ sudo apt --installed list | grep gir1.2-gstreamer-1.0
[...]
gir1.2-gstreamer-1.0/jammy,now 1.20.1-1 amd64 [installed,upgradable to: 1.20.3-0ubuntu1]

相同的命令会输出:
gir1.2-gstreamer-1.0/jammy,now 1.20.1-1 amd64 [installed,automatic]

在我的次要(虚拟)系统上。
为什么我们有这个差异?我该如何让我的主系统表现得像安装了该软件包的(虚拟)系统一样“自动”?

在我的“主要”系统上,命令apt-cache policy gir1.2-gstreamer-1.0的输出如下:

gir1.2-gstreamer-1.0:
  Installed: 1.20.1-1
  Candidate: 1.20.3-0ubuntu1
  Version table:
     1.20.3-0ubuntu1 500 (phased 30%)
        500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
 *** 1.20.1-1 500
        500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages
        100 /var/lib/dpkg/status

而在我的“次要”(虚拟)系统上就是这样的:
gir1.2-gstreamer-1.0:
  Installed: 1.20.1-1
  Candidate: 1.20.1-1
  Version table:
     1.20.3-0ubuntu1 1 (phased 30%)
        500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
 *** 1.20.1-1 500
        500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages
        100 /var/lib/dpkg/status

什么是值 500 (在 (phased... 行中)的含义?
在两个系统上,grep -ri phased /etc/apt 返回空。
在我的主系统上执行了命令sudo apt update && sudo apt upgrade gir1.2-gstreamer-1.0后:
$ sudo apt --installed list | grep gir1.2-gstreamer-1.0
[...]
gir1.2-gstreamer-1.0/jammy-updates,now 1.20.3-0ubuntu1 amd64 [installed]

$ apt-cache policy gir1.2-gstreamer-1.0
gir1.2-gstreamer-1.0:
  Installed: 1.20.3-0ubuntu1
  Candidate: 1.20.3-0ubuntu1
  Version table:
 *** 1.20.3-0ubuntu1 500 (phased 40%)
        500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     1.20.1-1 500
        500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages

现在,在我的辅助系统上,我也开始遇到这个问题了。
$ sudo apt upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  language-pack-gnome-en
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.

4在两个系统上比较apt-cache policy gir1.2-gstreamer-1.0 - nobody
500是软件包源的默认优先级,但这个阶段的部分是较新的,我不清楚;可能是因为我总是手动更新系统,所以从未在我的系统上遇到过。请在您的主系统上运行sudo apt update && sudo apt upgrade gir1.2-gstreamer-1.0 - nobody
好的,我找到了一些东西。https://askubuntu.com/questions/1331681/disable-phased-updates-in-20-04-lts - nobody
我更新了问题。 - FedKad
3个回答

分阶段更新是一项安全功能
  • 一些用户会首先获得升级包,并有能力报告损坏的软件包,而不是所有人同时获得一个损坏的软件包,导致数百万用户困惑不解。
它是为了保护您。不要试图聪明地绕过它。
  • 由于分阶段更新而被保留的软件包将自动在一周左右解决、下载和安装。
大多数用户应该什么都不做。它没有问题。不要试图强制升级。只需耐心等待并让系统工作。

诊断 -- 如何判断是否是分阶段更新的问题:

  • 很简单。在其中一个被拦截的软件包上运行apt-cache policy <packagename>命令。查找“phased”百分比。只有当软件包当前处于分阶段更新时才会显示。
$ apt-cache policy gir1.2-gstreamer-1.0
gir1.2-gstreamer-1.0:
  Installed: 1.20.3-0ubuntu1
  Candidate: 1.20.3-0ubuntu1
  Version table:
 *** 1.20.3-0ubuntu1 500 (phased 40%) <----------------- There it is!
        500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     1.20.1-1 500
        500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages

高级用法

  • 分阶段更新可以被禁用 - 这是一个简单的apt设置,但请记住,您正在禁用一个保护您免受损坏软件包的功能。您将自愿测试这些软件包!
  • 拥有多台机器的用户可以将这些机器设置为一起进行分阶段更新 - 这只是另一个简单的apt设置。

跳过一次分阶段更新的示例:

apt -o APT::Get::Always-Include-Phased-Updates=true upgrade

永久跳过分阶段的apt配置文件示例(不建议大多数用户使用)
cat <<EOF > /etc/apt/apt.conf.d/80PhasedUpdates
// Enable/Disable phased updates 
// Default is Phased Updates enabled. Use these lines to disable.
APT::Get::Never-Include-Phased-Updates: True;
Update-Manager::Never-Include-Phased-Updates;
EOF

使用每台机器上相同的apt配置文件来同步一组机器的相位示例:
cat <<EOF > /etc/apt/apt.conf.d/80PhasedUpdates
// To have multiple your machines phase the same, set the same
//   string in this field on all those machines
// If commented out or missing, apt will use /etc/machine-id to
//   seed the random number generator
APT::Machine-ID "aaaabbbbccccddddeeeeffff";
EOF

还可以参考在哪个`apt`配置文件中应该放置Never-Include-Phased-Updates标志?


在命令行中使用Always-Include-Phased-Updates=true可以一次性跳过分阶段更新,而在配置文件中使用Never-Include-Phased-Updates: True;可以永久跳过分阶段更新。我对这里的逻辑不太理解。 - undefined
@mook765 举例。有几种方法可以做到这一点。区别在于您是想先获取阶段性更新还是最后获取。 - undefined

这可能是由于“分阶段更新”系统的差异造成的。如果您在两台机器上运行此命令,看看软件包是否在两台机器上表现相同。
cat <<EOF > /etc/apt/apt.conf.d/80my
APT::Get::Always-Include-Phased-Updates "1";
EOF

更多有关分阶段更新的背景信息

21.04 中 APT 的分阶段更新

APT 现在实现了分阶段更新。之前,只有 update-manager 实现了分阶段更新...

这意味着在某些机器上会暂停一些更新,同时它们正在进行分阶段。这是通过从机器 ID、软件包名称和软件包版本获得的值来决定的。

apt_preferences 的手册页

APT 理解一个称为 Phased-Update-Percentage 的字段,可以用于控制新版本的发布。它是一个介于 0 到 100 之间的整数。

如果您有多个系统需要接收相同的更新集,您可以将APT::Machine-ID设置为UUID,以便它们都处于相同的阶段,或者将APT::Get::Never-Include-Phased-Updates或APT::Get::Always-Include-Phased-Updates设置为true,这样APT将永远/总是考虑分阶段更新。
手册还指出,“未分阶段”的版本将获得“优先级1”,这与您的apt-cache policy输出相匹配。

3是的!在我创建了你提到的文件/etc/apt/apt.conf.d/80my之后,两个系统上的所有“被保留”软件包都得到了升级。现在没有更多的被保留软件包了。不过,我打算在两个系统上删除这个文件并使用默认设置。最近Canonical似乎更积极地开始使用这种“分阶段更新”的系统,因为我在我的其他Ubuntu系统上也看到了相同的行为...感谢你的回答。 - FedKad


这帮助我在Ubuntu 22.04上安装了被拖延的软件包。 - CodeConnoisseur