在 Ubuntu 中使用 Apt 命令安装特定的软件包版本

想在 Ubuntu 中安装特定版本的软件包吗? 您可以通过以下方式“轻松”地做到这一点:

sudo apt install package_name=package_version

你怎么知道某个包有哪些版本可用? 使用这个命令:

apt list --all-versions package_name

在下面的屏幕截图中,您可以看到我有两个版本的 VLC 可用,我使用命令安装旧版本:

听起来像一个简单的任务,对吧? 但事情并不像看起来那么简单。 这里涉及几个如果和但。

本教程将涵盖使用 apt 或 apt-get 命令安装特定程序版本的所有重要方面。

关于安装特定版本程序的注意事项

您需要了解一些关于 APT 和存储库如何在 Ubuntu 和基于 Debian 的发行版中工作的知识。

没有来自同一来源的旧版本

Ubuntu 不会在存储库中保留旧版本的软件包。 在特定情况下,您可能会暂时看到多个版本。 例如,您运行 apt update(但不升级),并且有一个新版本可用。 您可能会在 apt 缓存中看到同一个包的两个版本。 但是,一旦软件包升级到新版本,旧版本就会从缓存以及存储库中删除。

对不同版本使用多个来源

要获得同一个包的多个版本,您必须添加多个源。 例如,VLC 在版本 3.x 中。 添加 VLC 每日构建 PPA 将给出(不稳定的)版本 4.x。

相似地, 您可以下载不同版本的 DEB 文件并安装它.

高版本总是优先

如果您从多个来源获得相同的软件包,默认情况下,Ubuntu 将安装最高可用版本。

在前面的示例中,如果我安装 VLC,它将安装版本 4.x,而不是 3.x。

旧版本升级到可用的新版本

这是另一个潜在的问题。 即使您安装了旧版本的软件包,它也会升级到新版本(如果可用)。 您必须持有该软件包并阻止其升级。

依赖也需要安装

如果包有依赖项,您还必须安装所需版本的依赖包。

现在您知道了一些潜在的问题,让我们看看如何解决它们。

安装特定版本的包

我在本教程中以 VLC 为例。 VLC 版本 3.0.16 在 Ubuntu 的存储库中可用。 我添加了每日构建 PPA,这为我提供了 VLC 4.0 版的候选发布版本。

如您所见,我现在系统中有两个可用的 VLC 版本:

[email protected]:~$ apt list -a vlc Listing... Done vlc/jammy 4.0.0~rc1~~git20220516+r92284+296~ubuntu22.04.1 amd64 vlc/jammy 3.0.16-1build7 amd64 vlc/jammy 3.0.16-1build7 i386

由于更高版本优先,使用 ‘apt install vlc’ 将导致安装 VLC 4.0。 但是为了本教程,我想安装旧版本 3.0.16。

sudo apt install vlc=3.0.16-1build7

但事情就是这样。 vlc 包有几个依赖项,这些依赖项也需要特定的版本。 但是,Ubuntu 会尝试为它们安装可用的更高版本,因此,您会收到经典的“您持有损坏的软件包”错误。

要解决此问题,您必须提供它抱怨的所有依赖包的特定版本。 所以这个命令变成了这样:

sudo apt install vlc=3.0.16-1build7  		 vlc-bin=3.0.16-1build7  		 vlc-plugin-base=3.0.16-1build7  		 vlc-plugin-qt=3.0.16-1build7  		 vlc-plugin-video-output=3.0.16-1build7  		 vlc-l10n=3.0.16-1build7  		 vlc-plugin-access-extra=3.0.16-1build7  		 vlc-plugin-notify=3.0.16-1build7  		 vlc-plugin-samba=3.0.16-1build7  		 vlc-plugin-skins2=3.0.16-1build7  		 vlc-plugin-video-splitter=3.0.16-1build7  		 vlc-plugin-visualization=3.0.16-1build7

如果您想知道,每行末尾的尾随 只是在多行上编写单个命令的一种方式。

它有效吗? 在许多情况下,它会。 但是我选择了一个复杂的 VLC 示例,它有很多依赖项。 即使是提到的依赖项也依赖于其他包。 它变得混乱。

另一种方法是在安装时指定源。

或者,指定存储库源

您已经添加了多个来源,因此您应该对包的来源有所了解。

使用以下命令并搜索存储库:

apt-cache policy | less

关注存储库名称之后的行:

500 https://security.ubuntu.com/ubuntu jammy-security/multiverse i386 Packages      release v=22.04,o=Ubuntu,a=jammy-security,n=jammy,l=Ubuntu,c=multiverse,b=i386      origin security.ubuntu.com

您可以指定 o、l、a 等参数。

在我最初的示例中,我想从 Ubuntu 的存储库(获得 3.16)而不是 PPA(给我 4)安装 VLC。

因此,下面的命令将安装 VLC 3.16 以及所有依赖项:

sudo apt install -t "o=ubuntu" vlc

看起来挺好的? 但是当您必须更新系统时,问题就来了。 然后它抱怨找不到指定的版本。

还有什么可以做的?

要安装旧版本,请从系统中删除新版本的源代码(如果可能)。 它有助于摆脱依赖地狱问题。

如果这不可行,请检查是否可以获取其他一些打包格式,如 Snap、Flatpak、AppImage 等。事实上,Snap 和 Flatpak 还允许您从可用版本中进行选择和安装。 由于应用程序是沙盒化的,因此更容易管理不同版本的依赖关系。

持有包并防止升级

如果您设法安装特定的程序版本,您可能希望避免意外升级到较新版本。 实现这一点并不太复杂。

sudo apt-mark hold package_name

您可以删除保留,以便以后升级:

sudo apt-mark unhold package_name

请注意,包的依赖项不会自动保存。 他们需要单独提及。

结论

如您所见,有一个规定可以安装程序的选定版本。 如果包有依赖关系,事情只会变得复杂。 然后你进入依赖地狱。

我希望你在本教程中学到了一些新东西。 如果您有任何问题或改进建议,请在评论部分告诉我。