第 2 章 Debian 软件包管理

[注意]注意

这一章假定最新的稳定版的代号为:bullseye

Debian 是一个志愿者组织,它建立一致的自由软件的预编译二进制包并从档案库中分发它们。

许多远程镜像站提供了 HTTP 和 FTP 的方式来访问 Debian 档案库。也可以使用 CD-ROM/DVD

Debian 软件包管理系统,当使用适当时,可以让用户从档案库安装统一设置的二进制软件包 到系统中。现在,有 62716 个可用于 amd64 架构的软件包。

Debian 软件包管理系统有丰富的历史,有许多可供选择的前端用户程序和后端访问方式。现在,我们推荐下列的这些。

  • apt(8) 用于所有的交互式命令行操作,包含软件包的安装、移除和升级。自 Debian Jessie(Debian 8)起可用。

  • apt-get(8) 用于从脚本中调用 Debian 软件包管理系统。它在 apt 不可用时也可作为一个备选选项(常见于较旧的 Debian 系统)。

  • aptitude(8) 使用一个交互式的文本界面来管理已安装的软件包和搜索可用的软件包。

表 2.1. Debian 软件包管理工具列表

软件包流行度大小说明
aptV:868, I:9994299高级软件包工具(APT), dpkg 的前端,提供了 “http” 、“ftp” 和 “file” 的档案库访问方式(包含 aptapt-getapt-cache 命令)
aptitudeV:80, I:4314249aptitude(8) ,基于终端的交互式软件包管理工具
taskselV:36, I:975393Debian 系统上对安装进行选择的工具(APT 的前端)
unattended-upgradesV:324, I:447325用于 APT 的增强软件包,会自动安装安全更新
dselectV:3, I:322591基于终端的软件包管理工具(之前的标准,APT 的前端和其它老的访问方式)
dpkgV:925, I:9996856用于 Debian 的软件包管理系统
synapticV:47, I:3207873图形化的软件包管理工具(GNOME 的 APT 前端)
apt-utilsV:339, I:9961162APT 实用程序:apt-extracttemplates(1) 、apt-ftparchive(1) 和 apt-sortpkgs(1)
apt-listchangesV:369, I:851421软件包历史更改提醒工具
apt-listbugsV:7, I:12465在每次 APT 安装前列出严重的 bug
apt-fileV:18, I:7890APT 软件包搜索工具 —— 命令行界面
apt-rdependsV:0, I:640递归列出软件包依赖

2.1. Debian 软件包管理的前提

2.1.1. 软件包配置

下面是 Debian 系统软件包配置的一些要点。

  • Debian 尊重系统管理员的手动配置。换句话说,软件包配置系统不会为了方便而去更改那些配置。

  • 每个软件包都带有自己的配置脚本,它使用标准用户接口 debconf(7) 来帮助软件包初始化安装过程。

  • Debian 开发者通过软件包配置脚本,尽力使你能有一个完美的升级体验。

  • 系统管理员可以使用软件包工具的全部功能。但在默认的安装中会禁用那些具有安全风险的。

  • 如果你手动激活了一些具有安全隐患的服务,你有责任遏制风险。

  • 高深的配置可以由系统管理员手动启用。这可能会对用于系统配置的通用流行帮助程序造成干扰。

2.1.2. 基本的注意事项

[警告]警告

不要从任何的混合套件中安装软件包。它可能会打破软件包的一致性,这需要你要深厚的系统管理知识,例如 ABI 编译器、版本和解释器特性等等。

Debian 系统管理员中的新手应该保持在只进行安全更新的 stable 版本。我的意思是,最好避免下列的一些行为作为一项预防措施,直到你十分了解 Debian 系统。下面有一些提醒。

  • 在 “/etc/apt/sources.list” 中不要包含 testingunstable

  • 在 “/etc/apt/sources.list” 里不要在标准的 Debian 中混合使用其它非 Debian 的档案库,例如 Ubuntu 。

  • 不要建立 “/etc/apt/preferences” 。

  • 不了解会造成的全部影响,就不要通过配置文件改变软件包管理工具的默认行为。

  • 不要使用 “dpkg -i <random_package>” 安装任何软件包。

  • 绝不使用 “dpkg --force-all -i <random_package>” 安装任何软件包。

  • 不要删除或修改 “/var/lib/dpkg/” 中的文件。

  • 不要让从源码直接安装的程序覆盖系统文件。

    • 如果需要的话,将它们安装到 “/usr/local” 或 “/opt” 中。

上述对 Debian 软件包管理系统做的行为所导致的不兼容影响可能会使你的系统无法使用。

负责有关键任务的服务器的严谨的 Debian 系统系统管理员,应该使用额外的预防措施。

  • 没有在安全的条件下使用你特定的配置进行彻底地测试,就不要从 Debian 安装任何软件包(包含安全更新)。

    • 你作为系统管理员要对你的系统负责到底。

    • Debian 系统长久的稳定史并无法保证什么。

2.1.3. 持续升级的生活

尽管我在上面进行了警告,我知道许多阅读这份文档的人还是想要使用 Debian 的 testingunstable 套件来作为他们自行管理的桌面环境的主系统。这是因为这些套件运行得很好,更新频繁,并提供了最新的特性。

[小心]小心

对于你的生产服务器,建议使用带有安全更新的 stable 套件。对于你只进行有限管理的桌面 PC 也是同样如此。

你只需要在 “/etc/apt/sources.list” 中简单地将发行版字符串设置为套件名:“testing” 或 “unstable”;或者代号:“bookworm” 或 “sid” 。这会使你享受持续升级的生活

使用 testingunstable很有乐趣的,但会带来一些风险。尽管 Debian 系统的 unstable 套件在大多数时候看起来都非常稳定,但在 Debian 系统的 testingunstable 套件中存在一些软件包问题,并且它们中的一部分是不容易解决的。这对你来说可能会很痛苦。有时候,你可能会有一个损坏的软件包或缺少某些功能几个星期。

这里有一些方法,可以使你简单快速地从 Debian 软件包的 bug 中恢复。

  • 通过将 Debian 系统的 stable 套件安装到另一个分区,可以使系统能够进行双启动

  • 制作安装 CD 便于用于 救援启动

  • 对软件包系统的基础设施有足够的了解来解决问题

  • 建立一个 chroot 或类似的环境来提前运行最新的系统(参见第 9.10 节 “虚拟化系统”

(如果你无法做到这些预防措施中的任何一个,那你可能还没做好使用 testingunstable 套件的准备。)

菩萨使用下面的内容拯救一个人,使他从挣扎于持续升级地狱因果报应中脱困,并让他达到 Debian 的极乐世界

2.1.4. Debian 档案库基础

让我们从系统用户的角度来看看 Debian 档案库

[提示]提示

Debian 档案库官方政策的定义参见 Debian 政策文档,第2章 —— Debian 档案库

对于典型的 HTTP 访问,档案库在 “/etc/apt/sources.list” 文件中像下面那样指定,例如,现在 stable = bullseye 系统。

  1. deb http://deb.debian.org/debian/ bullseye main contrib non-free
  2. deb-src http://deb.debian.org/debian/ bullseye main contrib non-free
  3. deb http://security.debian.org/ bullseye/updates main contrib
  4. deb-src http://security.debian.org/ bullseye/updates main contrib

这里,我倾向于使用代号 “bullseye” 来代替套件名 “stable” ,以避免下一个 stable 版本发布时出现意外。

/etc/apt/sources.list” 的含义在 sources.list(5) 中进行了描述,下面是一些要点。

  • deb” 的那行定义了二进制软件包。

  • deb-src” 的那行定义了源代码软件包。

  • 第一个参数是 Debian 档案库的根 URL 。

  • 第二个参数是发行版名称:可以使用套件名或代号。

  • 第三个和之后的参数是 Debian 档案库的有效档案库范围名称。

如果只是用 aptitude(它不访问源代码相关的元数据),“deb-src”那行可以安全地删掉(或者在文件开头添加 “#” 来将它注释掉)。这可以加速档案库元数据的更新。URL 可以是“http://” 、“ftp://” 、 “file://” ……

[提示]提示

如果在上述的例子中,使用了 “sid” 代替 “bullseye” ,那么 “/etc/apt/sources.list” 中的 “deb: http://security.debian.org/” 这行就不需要了。因为没有用于 “sid” (unstable)的安全更新的档案库。

下面是配置文件所使用的 Debian 档案库站点的 URL 和套件名或代号的列表。

表 2.2. Debian 档案库站点列表

档案库 URL套件名(代号)目的
http://deb.debian.org/debian/stable (bullseye)stable (bullseye) release 版本
http://deb.debian.org/debian/testing (bookworm)testing (bookworm) release 版本
http://deb.debian.org/debian/unstable (sid)unstable (sid) release 版本
http://deb.debian.org/debian/experimentalexperimental pre-release 版本(可选,只适用于开发者)
http://deb.debian.org/debian/stable-proposed-updates用于下一个稳定版本的更新(可选)
http://security.debian.org/stable/updates用于 stable release 版本的安全更新(重要)
http://security.debian.org/testing/updates用于 testing release 版本的安全更新(重要)
http://deb.debian.org/debian/bullseye-updates用于 bullseye 的垃圾邮件过滤器、IM客户端等的兼容更新
http://deb.debian.org/debian/bullseye-backports用于 bullseye 的较新的 backported 软件包(可选)
[小心]小心

只有带有安全更新的纯净的 stable release 版本可以提供最佳的稳定性。运行大多数 stable release 版本的软件包之中混合一些来自 testingunstable release 版本的软件包会比运行纯净的 unstable release 版本冒更大的风险,这是因为库版本的不匹配导致的。如果在 stable release 版本下你真的需要一些程序的最新版本,请使用来自 bullseye-updateshttp://backports.debian.org (参见 第 2.7.4 节 “更新和向后移植”)的软件包。使用这些软件包时必须额外小心。

[小心]小心

在 “deb“ 行中,你只需列出 stabletesting 或者 unstable 套件中的一个即可,如果你在 “deb“ 行中混合了 stabletestingunstable 套件,APT 程序的执行速度将会变慢并且只有最新的档案库是有用的。只有在 “/etc/apt/preferences“ 文件带有明确目标的时候,混合的列表才是有意义的。(查看第 2.7.3 节 “调整候选版本”)。

[提示]提示

对于使用 stabletesting 套件的 Debian 系统而言,在 “/etc/apt/sources.list” 中包含带有 “http://security.debian.org/” 的一行是不错的主意。它会启用安全更新。

[注意]注意

Debian 安全团体将会修正 stable 档案库的安全缺陷。这些行为是十分严格可靠的。testing 档案库中的缺陷,不一定会被 Debian 测试安全团体修正。由于一些原因,这些行为相对 stable 档案库没有那么严格,您可能需要等待已修正的 unstable 软件包移植到 testingunstable 档案库的缺陷,交由各个维护者修改。经常维护的unstable 软件包通常处于相当好的状况,因为它利用了上流最新的安全修正。有关 Debian 怎样处理安全缺陷,请参见 Debian安全常问问题

表 2.3. Debian 归档区域(area)列表

区域软件包数量软件包组件标准
main61595遵从 Debian 自由软件指导方针(DFSG),并且不依赖于 non-free
contrib349遵从 Debian 自由软件指导方针(DFSG),但依赖于 non-free
non-free772不遵从 Debian 自由软件指导方针(DFSG)

上述软件包的数量是 amd64 架构的。main 区域提供 Debian 系统(参见 第 2.1.5 节 “Debian 是100% 的自由软件”)。

通过把你的浏览器指向档案库 URL,这些 URL 在 distspool 之后是各不相同的,Debian 档案库能够被有规划的组织。

发行版可以用套件或代号来指定。发行版在许多文档中也被当做是套件的同义词。套件和代号的关系总结如下。

表 2.4. 套件和代号的关系

时间suite = stablesuite = testingsuite = unstable
bullseye 发布后codename = bullseyecodename = bookwormcodename = sid
bookworm 发布后codename = bookwormcodename = trixiecodename = sid

代号的历史参见 Debian FAQ: 6.2.1 以前用过哪些代号名?

在较严格的 Debian 档案术语,“部分 section”这一词特指按应用领域来分类的软件包类别。(但是,主要部分 (“main section”) 这一词有时会用来描述 Debian 档案区中,名为”main 主要”的区域 。)

Debian 开发者(DD)每次上传软件包到 unstable 档案库(通过 incoming 处理),都必须确保上传的软件包与最新的 unstable 档案库中的最新软件包兼容。

如果 DD 故意打破重要的库升级等的这种兼容性,这通常会在 Debian 开发者邮件列表等进行公告。

在 Debian 档案库维护脚本将软件包从 unstable 档案库移动到 testing 档案库前,档案库维护脚本不仅检查时间(约10天)和软件包的 RC bug 报告的状态,还尝试确保它们可以和最新的 testing 档案库中的软件兼容。这个过程使得testing 档案库非常正确可用。

通过由发布团队领导的逐步冻结档案库的过程,并进行一些手动干预,使 testing 档案库完全一致,无缺陷。然后,将旧的 testing 档案库的代码名称分配给新的 stable 档案库,并为新的 testing 档案库创建新的代码名称。新的 testing 档案库最初的内容和新发布的 stable 档案库的内容完全相同。

unstabletesting 档案库都可能会遭受由以下几个因素导致的临时的小故障。

  • 损坏的软件包被上传到档案库(多见于 unstable

  • 延迟接受新的软件包到档案库(多见于 unstable )

  • 档案库时间同步问题( testingunstable

  • 手动干预档案库,例如移除软件包(多见于 testing )等。

因此,如果你决定使用这些档案库,你应该能够修复或忍受这些类型的小故障。

[小心]小心

在新的 stable 版本发布后的几个月,大多数桌面用户应该使用带有安全更新的 stable 档案库,即使他们通常使用 unstabletesting 档案库。在这个过渡期中,unstabletesting 档案库不适合大多数人。你使用 unstable 档案库的系统是很难保持良好的工作状态的,因为它会遭受核心软件包的大量升级狂潮。 testing 档案库不大有用,因为它包含有和没有安全支持的 stable 档案库相同的内容(Debian testing 安全公告 2008-12)。一个月左右的时间后, 如果你仔细点的话, unstable 档案库或许可以使用。

[提示]提示

跟踪 testing 档案库时,由一个已移除的软件包引起的问题通常可以安装 unstable 档案库中相同的软件包(已修复 bug )来解决。

档案库的定义参见 Debian 政策文档

2.1.5. Debian 是100% 的自由软件

Debian 是100%的自由软件,因为:

  • Debian 默认只安装自由软件,这尊重了用户的自由。

  • Debian 在 main 中只提供自由软件。

  • Debian 建议只运行来自 main 的自由软件。

  • main 中的软件包没有依赖于在 non-freecontrib 中的软件包。

有人想知道下列的两个事实是否互相矛盾。

  • “ Debian 将始终是 100% 的自由软件”。( Debian 社群契约中的第一条)

  • Debian 服务器上有一些 non-freecontrib 软件包。

因为下列原因,这并不矛盾。

  • Debian 系统具有100%的自由,并且它的软件包位于 Debian 服务器的 main 区域。

  • Debian 系统之外的软件包位于 Debian 服务器的 non-freecontrib 区域。

Debian 社群契约的第4条和第5条对这进行了明确的解释:

  • 我们将优先考虑我们的用户及自由软件

    • 我们由我们的用户及自由软件社群的需要所导向。我们将优先考虑他们的利益。我们将在多种计算环境中支持我们的用户的操作需要。我们不反对在 Debian 系统上使用非自由软件,我们也不会尝试向创建和使用这部分软件的用户索取费用。我们允许他人,在没有我们的资金的参与下,制造包括 Debian 以及商业软件的增值套件。为了达成这些目标,我们将提供集成的、高质量的、100%自由的软件,而不附加任何可能阻止在这些方面使用的法律限制。
  • 哪些作品不符合我们的自由软件规范

    • 我们明了,某些我们的用户需要使用不符合 Debian 自由软件指导方针的作品。 我们为这些作品,在我们的档案库中留出了 “contrib“ 以及 “non-free“ 目录。在这些目录下的软件包,并不属于 Debian 系统 尽管它们已被配置成可以在 Debian 下使用。我们鼓励光盘制造商阅读这些目录下的软件的许可证,以判断他们是否可以在光盘中发行这些软件 。所以,尽管非自由软件并非 Debian 系统的一部分,我们仍支持它们的使用,并且我们为非自由软件提供了公共资源 (诸如我们的缺陷跟踪系统以及邮件列表)。

用户应该了解使用 non-freecontrib 中的软件包所需要冒的风险:

  • 使用类似的软件包会失去自由

  • 失去 Debian 对软件包的支持(这些软件包无法访问源代码,Debian 不能进行完全的支持。)

  • 污染你100%自由的 Debian 系统

Debian 自由软件指导方针Debian 设立了自由软件标准。Debian 对软件包中的软件做了最广泛的解释,包含文档、固件、图标和图形数据。这使得 Debian 的自由软件标准非常严格。

为了满足 main 严格的自由软件标准,Debian 曾经提供了 去掉 Mozilla 商标 的软件包(例如 Firefox 、Thunderbird 和 Seamonkey),它们移除了 logo 和一些图形数据;并将它们分别用 Iceweasel 、Icedove 和 Iceape 替代。在这些问题被解决后,这些软件包随着 Debian Stretch(Debian 9)的发布恢复了其原本的名称。

典型的 non-freecontrib 软件包包含了下列类型的自由分发的软件包:

  • GNU Free Documentation License下的文档包 ,包含不变的部分 ,比如GCC 和 Make的。 (大多数都可以在non-free/doc找到 .)

  • 包含没有源代码的二进制数据的固件软件包,例如在 第 9.9.6 节 “硬件驱动和固件” 中列出的 non-free 软件包。(多见于 non-free/kernel 部分。)

  • 游戏和字体软件包,对商业使用和/或内容修改进行了限制。

请注意,non-freecontrib 软件包的数量少于 main 软件包的2%。允许访问 non-freecontrib 并不会模糊软件包的来源。使用 aptitude(8) 的全屏交互式界面可以提供完全的可见性和完全的控制,可以让你决定安装来自某个部分的软件包,来使你的系统保持自由。

2.1.6. 软件包依赖关系

Debian 系统通过其控制文件字段中的版本化二进制依赖声明机制来提供一致的二进制软件包集合。下面有一些它们的简单定义。

  • “依赖”

    • 绝对的依赖,所有在这里列出的软件包都必须同时或提前安装。
  • “预依赖”

    • 类似于 Depends,但列出的软件包必须提前完成安装。
  • “推荐”

    • 这里表示一个强,但不是绝对的依赖关系 。大多数用户不会想要这个包,除非在这里列出的所有包都已经安装。
  • “建议”

    • 较弱的依赖。这个软件包的大多数用户可能会从安装所列的软件包中受益,但没有它们也可以有适当的功能。
  • “增强”

    • 这里表明一个像推荐的弱依赖关系,不装也没关系。
  • “破损”

    • 表明一个软件包不兼容一些版本规范。一般的解决方法就是升级列出的所有软件包。
  • “冲突”

    • 这表明了绝对的不兼容。为了安装这个软件包必须移除所有列出的软件包。
  • “替代”

    • 这表明这个文件安装的文件会替代所列的软件包的文件。
  • “提供”

    • 表明这个软件包会提供所列的软件包所有的文件和功能。
[注意]注意

请注意,同时将 “Provides” 、“Conflicts” 和 “Replaces” 定义到一个虚拟的软件包是一个明智的配置。这确保了在任何一个时间只能安装一个提供该虚拟包的真正软件包。

包含源代码依赖关系的官方定义位于 the Policy Manual: Chapter 7 - Declaring relationships between packages

2.1.7. 包管理的事件流

这是 APT 提供的软件包管理的简单事件流摘要。

  • 更新(“apt update”、“aptitude update” 或 “apt-get update”):

    1. 从远程档案库获取档案库元数据

    2. 重建和更新 APT 使用的本地元数据

    • 升级(“apt upgrade” 和 “apt full-upgrade”,或 “aptitude safe-upgrade” 和 “aptitude full-upgrade”,或 “apt-get upgrade” 和 “apt-get dist-upgrade”):
    1. 选择候选版本,它所安装的软件包通常都是最新的可用版本(例外参见 第 2.7.3 节 “调整候选版本”

    2. 解决软件包依赖关系

    3. 如果候选版本与已安装的版本不同,会从远程档案库获取所选择的二进制软件包

    4. 解包所获取的二进制软件包

    5. 运行 preinst 脚本

    6. 安装二进制文件

    7. 运行 postinst 脚本

  • 安装(“apt install ...”、“aptitude install ...“ 或者 “apt-get install …” ):

    1. 选择命令行中列出的包

    2. 解决软件包依赖关系

    3. 从远程服务器获取已选二进制包

    4. 解包所获取的二进制软件包

    5. 运行 preinst 脚本

    6. 安装二进制文件

    7. 运行 postinst 脚本

  • 移除 (”apt remove …“, “aptitude remove …” 或 “apt-get remove …”):

    1. 选择命令行中列出的包

    2. 解决软件包依赖关系

    3. 运行 prerm 脚本

    4. 移除已安装的文件,除了配置文件

    5. 运行 postrm 脚本

  • 清除 (”apt purge“,“aptitude purge …” 或 “apt-get purge …”):

    1. 选择命令行中列出的包

    2. 解决软件包依赖关系

    3. 运行 prerm 脚本

    4. 移除已安装的文件,包含配置文件

    5. 运行 postrm 脚本

这里,为了大局,我特意省略了技术细节。

2.1.8. 对包管理问题的第一个回应

你应该阅读优良的官方文档。第一个阅读的文档是 Debian 特定的 “/usr/share/doc/<package_name>/README.Debian”。同时也应该查询 “/usr/share/doc/<package_name>/” 中的其它文档。如果你设置 shell 为第 1.4.2 节 “定制bash”,输入下列命令。

  1. $ cd <package_name>
  2. $ pager README.Debian
  3. $ mc

你可能需要安装以 “-doc” 后缀命名的对应文档软件包来获取详细的信息。

如果你在使用一个特定的软件包时出现了问题,一定要首先检查 Debian bug 跟踪系统(BTS) 网站。

表 2.5. 解决特定软件包问题的主要网站

网站命令
Debian bug 跟踪系统(BTS) 的主页sensible-browser “http://bugs.debian.org/
软件包名称已知的 bug 报告sensible-browser “http://bugs.debian.org/<package_name&gt;”
bug 编号已知的 bug 报告sensible-browser “http://bugs.debian.org/<bug_number&gt;”

使用 Google 搜索,在关键字中包含 “site:debian.org”,“site:wiki.debian.org”,“site:lists.debian.org” 等等。

当你要发送一份 bug 报告时,请使用 reportbug(1) 命令。

2.2. 基础软件包管理操作

在 Debian 系统中有许多基于 APT 的软件包管理工具可以在 Debian 系统上进行基于仓库的软件包管理操作。在这里,我们将介绍 3 种基本的软件包管理工具:apt,apt-get / apt-cacheaptitude

对于涉及软件包安装或更新软件包元数据的软件包管理操作,你必须有 root 权限。

2.2.1. apt vs. apt-get / apt-cache vs. aptitude

尽管 aptitude 是作者主要使用的一个非常好的可互动工具,但你应该知道下列警示:

  • 不建议在新版本发布后在 stable Debian 系统上使用 aptitude 命令来进行跨版本的系统升级。

    • 建议使用”apt full-upgrade“或“apt-get dist-upgrade” 来进行这个操作。参见 Bug #411280
  • aptitude命令有时候会为了testingunstable Debian 系统升级清除大量软件包。

    • 这个情况吓坏了许多的系统管理员。请不要惊慌。

    • 这似乎大多数是由元软件包的依赖或推荐的软件包版本偏差造成的,例如 gnome-core

    • 要解决这个问题,可以在 aptitude 命令菜单中选择 “取消待执行的动作” ,退出 aptitude,并使用 “apt full-upgrade”。

apt-getapt-cache 是最基础 的基于 APT 的软件包管理工具。

  • apt-getapt-cache 只提供命令行用户界面。

  • apt-get 是进行跨版本的主系统升级等操作的最合适工具。

  • apt-get 提供了一个强大的软件包依赖解析器。

  • apt-get 对硬件资源的要求不高。它消耗更少的内存并且运行速度更快。

  • apt-cache 提供了一个 标准的正则表达式来搜索软件包名称和描述。

  • apt-getapt-cache 可以使用 /etc/apt/preferences 来管理软件包的多个版本,但这非常繁琐。

apt 命令是一个用于软件包管理的高级命令行界面。它基本上是 apt-getapt-cache 和类似命令的一个封装,被设计为针对终端用户交互的界面,它默认启用了某些适合交互式使用的选项。

  • apt 工具在用户使用 apt install 安装软件包时提供了一个友好的进度条。

  • 在成功安装下载的软件包后,apt 将默认删除缓存的 .deb 软件包。

[提示]提示

建议用户使用新的 apt(8) 命令用于 交互式的使用场景,而在 shell 脚本中使用 apt-get(8) 和apt-cache(8) 命令。

aptitude 命令是最通用的基于 APT 的软件包管理工具。

  • aptitude 提供了一个全屏的交互式文本用户界面。

  • aptitude 同样也提供了一个命令用户界面。

  • aptitude 是用于日常软件包管理(例如检查已安装的软件包和搜索可用的软件包)的最合适工具。

  • aptitude 对硬件资源的要求更高。它消耗更多的内存并且运行速度更慢。

  • aptitude 提供一个增强的正则表达式来搜索所有的软件包元数据。

  • aptitude 可以管理软件包的多个版本,并且不使用 /etc/apt/preferences,这会十分直观。

2.2.2. 命令行中的基础软件包管理操作

下面是使用 apt(8), aptitude(8) 和 apt-get(8) / apt-cache(8) 的命令行基本软件包管理操作。

表 2.6. 使用 apt(8), aptitude(8) 和 apt-get(8) / apt-cache(8) 的命令行基本软件包管理操作

apt 语法aptitude 语法apt-get / apt-cache 语法说明
apt updateaptitude updateapt-get update更新软件包档案库元数据
apt install fooaptitude install fooapt-get install foo安装 “foo” 软件包的候选版本以及它的依赖
apt upgradeaptitude safe-upgradeapt-get upgrade安装已安装的软件包的候选版本并且不移除任何其它的软件包
apt full-upgradeaptitude full-upgradeapt-get dist-upgrade安装已安装的软件包的候选版本,并且需要的话会移除其它的软件包
apt remove fooaptitude remove fooapt-get remove foo移除 “foo” 软件包,但留下配置文件
apt autoremoveN/Aapt-get autoremove移除不再需要的自动安装的软件包
apt purge fooaptitude purge fooapt-get purge foo清除 “foo” 软件包的配置文件
apt cleanaptitude cleanapt-get clean完全清除本地仓库的软件包检索文件
apt autocleanaptitude autocleanapt-get autoclean清除本地仓库中过时软件包的软件包检索文件
apt show fooaptitude show fooapt-cache show foo显示 “foo” 软件包的详细信息
apt search <正则表达式>aptitude search <regex>apt-cache search <regex>搜索匹配 <regex> 的软件包
N/Aaptitude why <regex>N/A解释匹配 <regex> 的软件包必须被安装的原因
N/Aaptitude why-not <regex>N/A解释匹配 <regex> 的软件包不必安装的原因
N/Aaptitude search ‘~i!~M’apt-mark showmanual列出手动安装的软件包
[注意]注意

虽然 aptitude 命令提供了丰富的功能,例如增强的软件包解析器,但它的复杂程度导致了(或可能导致)一些退步,例如 Bug #411123Bug #514930Bug #570377。如有疑问,请使用 apt,apt-getapt-cache 命令来替代 aptitude 命令。

[注意]注意

因为在 lenny 版本之后的 Debian 系统中, aptapt-getaptitude 会共享自动安装的软件包的状态(参见第 2.5.5 节 “APT 的软件包状态”),因此你可以混合使用这些工具而不会出现严重的麻烦(参见 Bug #594490)。

aptitude why <regex>” 可以通过 “aptitude -v why <regex>” 列出更多的信息。类似的信息可以通过”apt rdepends <package>“ 或 “apt-cache rdepends <package>” 获取。

aptitude 命令在命令行模式下启动后遇到了一些问题(例如软件包冲突),你可以在之后的提示中按下 “e” 键切换到全屏的交互模式。

你可以在 “aptitude” 后面使用的命令选项。

表 2.7. aptitude(8) 中重要的命令选项

命令选项说明
-s模拟命令的结果
-d仅下载,不进行安装/更新
-D在自动安装和删除前,显示简要的说明

更多内容参见 aptitude(8) 和位于 “/usr/share/doc/aptitude/README” 的 “aptitude 用户手册”。

[提示]提示

dselect 软件包依旧可用,并且曾是之前发布的版本中首选的全屏交互式软件包管理工具。

2.2.3. aptitude 的交互式使用

要使用交互式的软件包管理,你可以像下面那样以交互模式启动 aptitude

  1. $ sudo aptitude -u
  2. Password:

这将更新档案库信息的本地副本,并以菜单的形式全屏显示软件包列表。 aptitude 将它的配置放在 “~/.aptitude/config”。

[提示]提示

如果你想用 root 的配置而非使用者的,可以在上面的例子中使用 “sudo -H aptitude …” 代替 “sudo aptitude …” 。

[提示]提示

aptitude 以交互模式启动时,会自动设置待执行的动作。如果您不喜欢,您可以通过菜单:“动作” → “取消待执行的动作” 来取消它。

2.2.4. aptitude 的按键绑定

在全屏模式下浏览软件包状态和设置动作的按键如下。

表 2.8. aptitude 的按键绑定

快捷键键绑定功能
F10Ctrl-t菜单
?显示按键帮助(更加完整的清单)
F10 → 帮助 → 用户手册显示用户手册
u更新软件包档案库信息
+标记该软件包以便升级安装
-标记该软件包以便移除(保留配置文件)
_标记该软件包以便清除(移除配置文件)
=将软件包设为保持状态
U标记所有可升级包(动作如同 full-upgrade
g开始 下载安装 所选择包
q退出该界面并保存变更
x退出该界面并清除变更
Enter查看软件包的信息
C查看软件包的变更记录
l变更软件包的显示限制
/搜寻匹配的第一个软件包
\重复上一个搜索

可以通过命令行指定文件名称,也可以通过按 “l” 或 “/” 之后在菜单提示下输入下列所述的 aptitude 正则表达式。aptitude 正则表达式可以使用 “~n” 开头后接软件包名称的字符串来精确匹配软件包名称。

[提示]提示

你需要在可视化界面中按下 “U” 键让所有的已安装软件包升级到可用版本 。否则只有选中的软件包和一些与之有依赖关系的软件包才能被升级到可用版本

2.2.5. aptitude 软件包视图

aptitude(8) 全屏交互模式下,软件包列表里的软件包会像下面的例子那样显示。

  1. idA libsmbclient -2220kB 3.0.25a-1 3.0.25a-2

该行的从左到右的含义如下。

  • “状态”标签 (第一个字母)

  • “动作”标签(第二个字母)

  • “自动”标签(第三个字母)

  • 软件包名称

  • 该“动作”对磁盘空间的变化

  • 软件包当前版本

  • 软件包可用版本

[提示]提示

您可以在帮助菜单中找到完整的标签列表,按“?”即可在帮助菜单底部显示。

可用版本 的选择是依据当前的本地首选项(参见 apt_preferences(5) 和 第 2.7.3 节 “调整候选版本”)。

软件包视图的几种类型都可以在“ 视图 ”菜单下找到。

表 2.9. aptitude 视图

视图状态视图描述
软件包视图良好参见 表 2.10 “标准软件包视图的分类” (默认)
检查推荐结果良好列出推荐安装但还没有安装的软件包
平面软件包列表良好不分类地列出软件包 (用于正则表达式)
Debtags 浏览器非常有用列出由 debtags 进行分类的软件包
分类浏览器已弃用列出按照类别分类的软件包(用Debtags 浏览器替代)
[注意]注意

请帮助我们改进用 debtags 标记的软件包!

标准“软件包视图”分类软件包的方法与带有一些额外功能的 dselect 有点像。

表 2.10. 标准软件包视图的分类

分类视图描述
可升级软件包按照 sectionarea软件包 的顺序显示列出软件包
新软件包同上
已安装软件包同上
未安装软件包同上
过期的和在本地创建的软件包同上
虚拟软件包列出同样功能的软件包
软件集列出一个特定任务所需的不同功能的软件包
[提示]提示

软件集视图可以用来为你的任务选出最佳的软件包。

2.2.6. aptitude 搜索方式选项

aptitude 提供了几个可以使用正则表达式来搜索软件包的选项。

  • shell 命令行:

    • aptitude search '<aptitude_regex>'” 列出安装状态、软件包名称和匹配软件包的剪短描述

    • aptitude show '<package_name>'” 列出软件包的详细描述

  • 全屏交互模式:

    • l“ 可以限制匹配软件包的视图

    • /“ 搜索匹配的软件包

    • \“ 向后搜索匹配的软件包

    • n“ 查找下一个

    • N“ 查找上一个

[提示]提示

字符串 <package_name> 被看作软件包名称的精确字符串匹配,除非它是以 “~“ 开头的正则表达式。

2.2.7. aptitude 正则表达式

aptitude 正则表达式是类 mutt 的拓展 ERE(参见 第 1.6.2 节 “正则表达式”),aptitude 具体的特殊匹配规则扩展如下。

表 2.11. aptitude 正则表达式

扩展匹配规则描述正则表达式
匹配软件包名称~n<regex_name>
匹配描述~d<regex_description>
匹配软件集名称~t<regex_task>
匹配 debtag~G<regex_debtag>
匹配维护者~m<regex_maintainer>
匹配软件包的 section~s<regex_section>
匹配软件包版本~V<regex_version>
匹配档案库~A{bullseye,bookworm,sid}
匹配来源~O{debian,…}
匹配优先级~p{extra,important,optional,required,standard}
匹配必要的软件包~E
匹配虚拟软件包~v
匹配新的软件包~N
匹配待执行的动作~a{install,upgrade,downgrade,remove,purge,hold,keep}
匹配已安装软件包~i
匹配带有 A 标签的已安装软件包(自动安装的软件包)~M
匹配不带有 A 标签的已安装软件包(管理员选择的软件包)~i!~M
匹配已安装并且是可升级的软件包~U
匹配已删除但未清除的软件包~c
匹配已移除,已清除或可移除的软件包~g
匹配破坏依赖关系的软件包~b
匹配破坏 <type> 依赖关系的软件包~B<类型>
匹配 <pattern> 软件包的 <type> 依赖关系~D[<类型>:]<模式>
匹配 <pattern> 软件包破坏的 <type> 依赖关系~DB[<类型>:]<模式>
匹配依赖于 <pattern> 软件包的 <type> 依赖的软件包~R[<类型>:]<模式>
匹配依赖于 <pattern> 软件包破坏的 <type> 依赖的软件包~RB[<类型>:]<模式>
匹配其它已安装软件包所依赖的软件包~R~i
匹配没有被其它已安装软件包所依赖的软件包!~R~i
匹配其它已安装软件包所依赖或建议安装的软件包~R~i|~R推荐:~i
匹配 <pattern> 过滤版本之后的软件包~S 过滤 <模式>
匹配所有软件包(真)~T
不匹配软件包(假)~F
  • 正则表达式使用的是 ERE,就跟 egrep(1)、awk(1) 和 perl(1) 这些典型的类 Unix 文本工具中所使用的 “^”、“.*”、“$” 等是相同的。

  • 依赖关系 <type> 是一种特定的软件包相互关系(depends、predepends、recommends、suggests、conflicts、replaces、provides)。

  • 默认的 <type> 依赖关系是 “depends”。

[提示]提示

当 <regex_pattern> 为空字符串时,请立即在命令后面添加 “~T“。

下面是一些快捷方式。

  • ~P<term>“ == “~Dprovides:<term>

  • ~C<term>“ == “~Dconflicts:<term>

  • …~W term“ == “(…|term)

用户熟悉 mutt 的快速选择,因为 mutt 的灵感来源于表达式语法。参见 “用户手册” “/usr/share/doc/aptitude/README” 中的 “SEARCHING, LIMITING, AND EXPRESSIONS”。

[注意]注意

lenny 版本的 aptitude(8) 中,新的长格式语法,例如 “?broken”,在正则表达式中可以用来等效为它旧的短格式~b”。现在空格字符 “ ” 被认为是除了波浪字符 “~” 外的另一个正则表达式终止字符。新的长格式语法参见 “用户手册”。

2.2.8. aptitude 的依赖解决

如果通过菜单 “F10 → 选项 → 首选项 → 正在处理依赖关系” 进行相应的设置,则在 aptitude 中选择一个软件包时,不仅会将其 “Depends:” 列表中的软件包选上,“Recommends:” 列表中的软件包也会被选上。在 aptitude 下,这些自动安装的软件包在不再需要时会自动移除。

aptitude 命令中控制 “自动安装” 行为的标签也可以通过 apt 软件包中的 apt-mark(8) 命令来设置。

2.2.9. 软件包活动日志

你可以在日志文件里查询到软件包活动历史。

表 2.12. 软件包活动日志文件

文件内容
/var/log/dpkg.logdpkg 级的软件包活动日志
/var/log/apt/term.log通用 APT 活动日志
/var/log/aptitudeaptitude 命令活动日志

事实上,很难从这些日志上快速获得有用的信息。较简便的方法参见 第 9.2.10 节 “记录配置文件的变更”

2.3. aptitude 操作范例

下面是一些 aptitude(8) 的操作范例。

2.3.1. 通过正则表达式匹配软件包名称来列出软件包

下面的命令列出了通过正则表达式匹配软件包名称来列出软件包。

  1. $ aptitude search '~n(pam|nss).*ldap'
  2. p libnss-ldap - 使用 LDAP 作为名称服务的 NSS 模块
  3. p libpam-ldap - 允许 LDAP 接口的插入式验证模块

这种方式查找精确的软件包名称很方便。

2.3.2. 使用正则表达式匹配浏览

在”新扁平软件包列表” 中使用 “l“ 提示查看,正则表达式 “~dipv6“ 可以限制性地匹配软件描述,并交互式地展示信息。

2.3.3. 完整地清理已删除软件包

您能清除所有已移除软件包的剩余配置文件。

检查以下命令的结果。

  1. # aptitude search '~c'

如果您确认所列出的软件包应当被完整删除,请运行以下命令。

  1. # aptitude purge '~c'

您可能想要在交互模式中做类似的操作进行细粒度的控制。

在 “新软件包视图” 使用 “l“ 提示并输入正则匹配式 “~c“ ,这将仅匹配软件包,比如, “移除但不清空配置” 。所有符合匹配的软件包可以在顶层标题上使用 “[“ 显示。

当您在顶层标题如 “未安装的包” 中输入 “_”,当前标题下的软件包只有匹配正则式才会被清除。您还可以使用“=” 来交互式地排除软件包以避免删除它们。

这种技术方便易用且适用于许多其他的命令键。

2.3.4. 调整自动/手动安装状态

下面是调整软件包的自动/手动安装状态的方法(在使用非 aptitude 软件包管理器之后)。

  1. 用 root 以交互模式运行 aptitude

  2. 用 “u“ 命令更新可用的软件包列表,”U“ 命令标记所有可升级的软件包以执行升级,”f“ 命令清除新软件包列表,”g“ 命令执行所有可升级的软件包以执行升级。

  3. 按下 “l”,并输入 “~i(~R~i|~Rrecommends:~i)” 来限制软件包的显示,按下 “M” 将 “已安装软件包” 的状态改为自动安装。

  4. 按下 “l”,并输入 “~prequired|~pimportant|~pstandard|~E” 来限制软件包的显示,按下 “m” 将 “已安装软件包” 的状态改为手动安装。

  5. 按下 “l”,并输入 “~i!~M” 来限制软件包的显示,在 “已安装软件包” 上按下 “[” 来陈列无用的软件包,按下 “-” 将它们移除。

  6. 按下 “l”,并输入 “~i” 来限制软件包的显示,之后在 “软件集” 上按下 “m” 将那些软件包标记为手动安装。

  7. 退出 aptitude

  8. 用 root 用户执行 “apt-get -s autoremove|less“ 命令,来查看有那些软件包是不再需要的。

  9. 在交互模式下重启 aptitude 程序,用 “m” 命令标记所需要的软件包。

  10. 用 root 用户重新执行 “apt-get -s autoremove|less“ 这个命令来复查移除的包中是不是只含有自己所希望移除的软件包。

  11. 用 root 用户执行 “apt-get autoremove|less“ 命令来自动移除不再需要的软件包。

在你所需要执行的 “Tasks“ 上,运行 “m“ 命令是一个可选的操作,目的就是为了防止大量软件包被卸载的情况出现。

2.3.5. 全面的系统升级

[注意]注意

当你迁移到新的发行版的时候,虽然正如下面所描述的那样,Debian 是可升级的,但是你还是应该考虑纯净的安装新的系统。这给了你机会去移除废弃的软件包同时还可以接触到最新软件包的完美集合体。当然,在做迁移之前,你也应该对你的系统做完整的备份,并把它移到安全的地方去(查看第 10.2 节 “备份和恢复”)。“我”也建议用不同的分区做另外一个启动项,来实现平稳的升级。

你可以通过改变 “/etc/apt/sources.list“ 的内容使之指向新的发行版所在地址的方法来进行系统的全面升级,然后运行 “apt update; apt dist-upgrade“ 命令。

stable 升级到 testing 或者 unstable,你应该用 “bookworm“ 或者 “sid“ 替换 “/etc/apt/sources.list“ 文件里的 “bullseye“,参考 第 2.1.4 节 “Debian 档案库基础”

事实上,由于一些软件包版本变迁的问题,你可能会遇到一些困难,主要是由于软件包的依赖问题。升级之后的差异越大,你越有可能遇到麻烦。在新版本发行后,系统从旧的 stable 过渡到新的 stable,你可以查看 Release Notes 然后按照里面的步骤去做,来尽可能的减少麻烦。

在它正式发布之前,你决定要从先前的 stable 迁移到将要发布的 testing,这里没有 Release Notes 可以帮到你。 在前一个 stable 发布以后, stable 发行版跟将要发布的 testing 发行版之间的差异可能变得相当大同时也使得升级系统变得更加的复杂。

在全面升级系统的时候,你应该谨慎的操作,同时你也应该从邮件列表中获取最新的资料然后根据你的常识作出正确的判断。

  1. 查看先前的“发行说明”。

  2. 备份整个系统(尤其是数据和配置信息)。

  3. 当 bootloader 坏了的时候,手边应该有可以引导电脑启动的存储介质。

  4. 事先通知系统上的用户。

  5. 用 script(1) 记录升级的过程。

  6. 用 “unmarkauto” 命令来保留你想要的软件包,例如 “aptitude unmarkauto vim“ 这个命令是用来防止移除vim这个软件的。

  7. 为了减少软件包之间可能会发生的冲突,应该尽量减少要安装的软件包的数目,例如,移除桌面环境这个软件包。

  8. 移除 “/etc/apt/preferences“ 文件(禁用apt-pinning)。

  9. 试着一步步的升级: oldstablestabletestingunstable.

  10. 升级 “/etc/apt/sources.list“ 文件,使其指向新的档案库然后运行 “aptitude update“ 命令。

  11. 可选的安装选项,首先是新的 core packages,例如 “aptitude install perl“。

  12. 运行 “apt-get -s dist-upgrade“ 命令来评估升级造成的影响。

  13. 最后运行 “apt-get dist-upgrade“ 命令。

[小心]小心

stable 版本升级的时候,跳过主要的 Debian 发行版是不明智的。

[小心]小心

在先前的“发行手册”里, GCC, Linux Kernel, initrd-tools, Glibc, Perl, APT tool chain 等等,有一些关于系统全面升级的重要注意事项。

关于 unstable 版本的日常升级,查看 第 2.4.3 节 “预防软件包故障”

2.4. 高级软件包管理操作

2.4.1. 命令行中的高级软件包管理操作

下面列出了一些其它的软件包管理操作,这些操作对于 aptitude 过于高级或缺失所需的功能。

表 2.13. 高级软件包管理操作

命令操作
COLUMNS=120 dpkg -l <packagename_pattern>列出已安装软件包的列表用于错误报告
dpkg -L <package_name>显示一个已安装软件包的内容
dpkg -L <package_name> | egrep ‘/usr/share/man/man.*/.+’列出一个已安装软件包的 man 手册页
dpkg -S <file_name_pattern>列出匹配文件名的已安装软件包
apt-file search <file_name_pattern>列出档案库中匹配文件名的软件包
apt-file list <package_name_pattern>列出档案库中匹配的软件包的内容
dpkg-reconfigure <package_name>重新配置软件包
dpkg-reconfigure -p=low <package_name>通过最详细的方式来重新配置软件包
configure-debian以全屏菜单的形式重新配置软件包
dpkg —audit部分安装软件包的审计系统
dpkg —configure -a配置所有部分安装的软件包
apt-cache policy <binary_package_name>显示一个二进制软件包的可用版本、优先级和档案库信息
apt-cache madison <package_name>显示一个软件包的可用版本和档案库信息
apt-cache showsrc <binary_package_name>显示一个二进制软件包的源代码软件包信息
apt-get build-dep <package_name>安装构建软件包所需要的软件包
aptitude build-dep <package_name>安装构建软件包所需要的软件包
apt-get source <package_name>(从标准档案库)下载源代码
dget <URL for dsc file>(从其它档案库)下载源代码软件包
dpkg-source -x <package_name><version>-<debianversion>.dsc从源代码软件包集合(“.orig.tar.gz” 和 “.debian.tar.gz“/“*.diff.gz”)中构建代码树
debuild binary从本地的源代码树中构建软件包
make-kpkg kernel_image从内核源代码树中构建一个内核软件包
make-kpkg —initrd kernel_image从启用了 initramfs 的内核代码树中构建一个内核软件包
dpkg -i <package_name><version>-<debianversion><arch>.deb安装一个本地的软件包到系统中
apt install /path/to/<packagefilename>.deb安装本地软件包到系统中,同时尝试自动解决依赖
debi <package_name><version>-<debianversion><arch>.dsc安装本地软件包到系统中
dpkg —get-selections ‘*’ >selection.txt保存 dpkg 级别的软件包选择状态信息
dpkg —set-selections <selection.txt使用 dpkg 设置软件包选择状态
echo <package_name> hold | dpkg —set-selections使用 dpkg 将一个软件包的包选择状态设置为 hold(相当于 “aptitude hold < 包名> “)
[注意]注意

对于一个支持多架构的软件包,你可能需要为一些命令指定架构名称。例如,使用 “dpkg -L libglib2.0-0:amd64” 来列出 amd64 架构的 libglib2.0-0 软件包的内容。

[小心]小心

系统管理员应该小心使用低级的软件包工具(例如 “dpkg -i …” 和 “debi …”),它们不会自动处理所需的软件包依赖。 dpkg 的命令行选项 “—force-all” 和类似的选项(参见 dpkg(1))只适用于高手。没有完全理解它们的效果却使用它们会破坏你的整个系统。

请注意以下几点。

  • 所有的系统配置和安装命令都需要以 root 运行。

  • apt-file(1) 由 apt-file 软件包提供,并且需要先运行 “apt-file update”。

  • configure-debian(8) 由 configure-debian 软件包提供,它运行 dpkg-reconfigure(8) 作为后端。

  • dpkg-reconfigure(8) 使用 debconf(1) 作为后端来运行软件包脚本。

  • apt-get build-dep“ 、”apt-get source“ 和 “apt-cache showsrc“ 命令需要 “/etc/apt/sources.list“ 中存在 “deb-src“ 条目。

  • dget(1) 、debuild(1) 和 debi(1) 需要 devscripts 软件包。

  • 参见 第 2.7.13 节 “移植一个软件包到 stable 系统” 里使用 “apt-get source“ 的打包(重打包)过程。

  • make-kpkg 命令需要 kernel-package 软件包(参见 第 9.9 节 “内核”)。

  • 通用打包参见 第 12.11 节 “制作 Debian 包”.

2.4.2. 验证安装的软件包文件

已经安装 debsums 软件包的,能使用 debsums(1) 命令通过 “/var/lib/dpkg/info/*.md5sums“ 文件中的 MD5sum 值,验证已安装的文件。参见第 10.3.5 节 “MD5 校验和”来获得 MD5sum 是怎样工作的信息。

[注意]注意

因为 MD5sum 数据库可能被侵入者篡改,debsums(1) 作为安全工具使用有限。这种工具用于校验管理者造成的本地修改或媒体错误造成的损坏是很不错的。

2.4.3. 预防软件包故障

许多用户更想使用 unstable,因为它有新的功能和软件包。但这会使得系统更容易遇到严重的软件包 bug 。

安装软件包 apt-list bugs 可以避免您的系统遭遇严重 bugs,在通过 APT 系统升级时,它会自动检查 Debian BTS 里的严重 bug。

安装 apt-listchanges 软件包,在使用 APT 系统升级时它会在 “NEWS.Debian” 中提供重要新闻。

2.4.4. 搜索软件包元数据

尽管近来浏览 Debian 网站 https://packages.debian.org/ 是搜索软件包元数据更加简单的方法,但我们依旧来看看更传统的方法。

grep-dctrl(1) 、grep-status(1) 和 grep-available(1) 命令被用来搜索具有 Debian 软件包控制文件格式的任何文件。

dpkg -S <file_name_pattern>” 被用来搜索由 dpkg 安装的软件包中包含匹配文件的。但它会忽略维护者的脚本创建的文件。

如果你需要对 dpkg 元数据进行更复杂的搜索,你需要在 “/var/lib/dpkg/info/” 目录下运行 “grep -e regex_pattern *” 命令。这会使你在软件包脚本和安装查询文本中搜索提及的单词。

如果你想递归查找软件包依赖,你应该使用 apt-rdepends(8) 。

2.5. Debian 软件包内部管理

让我们来学习 Debian 软件包管理的内部工作原理。这应该能够帮助你独立解决一些软件包问题。

2.5.1. 档案库元数据

每个发行版的元数据文件都保存在 Debian 镜像站的 “dist/<codename>” 下面,例如 “http://deb.debian.org/debian/”。档案库的结构可以通过网络浏览器来浏览。其中有 6 种关键的元数据。

表 2.14. Debian 档案库元数据的内容

文件位置内容
Release发行版的顶层档案库描述和完整性信息
Release.gpg发行版的顶层Release“ 文件的签名文件,使用档案库密钥签名
Contents-<architecture>发行版的顶层列出在相关架构中所有软件包的全部文件
Release每个发行版/区域/架构组合的顶部归档描述使用 apt_preferences( 5 ) 的规则
Packages每个发行版/区域/二进制架构组合的顶部连接 debian/control 获得二进制包
Sources每个 发行版/区域/源代码 组合的顶部连接 debian/control 获取源代码包

为了减少网络流量,在最近的档案库中,这些元数据存储为压缩了的差分文件。

2.5.2. 顶层“Release”文件及真实性

[提示]提示

顶层“Release”文件用于签署secure APT系统下的归档文件。

每个 Debian 档案库的网址都有一个这样的 “Release” 文件,例如 “http://deb.debian.org/debian/dists/unstable/Release”,内容如下。

  1. Origin: Debian
  2. Label: Debian
  3. Suite: unstable
  4. Codename: sid
  5. Date: Sat, 14 May 2011 08:20:50 UTC
  6. Valid-Until: Sat, 21 May 2011 08:20:50 UTC
  7. Architectures: alpha amd64 armel hppa hurd-i386 i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc
  8. Components: main contrib non-free
  9. Description: Debian x.y Unstable - Not Released
  10. MD5Sum:
  11. bdc8fa4b3f5e4a715dd0d56d176fc789 18876880 Contents-alpha.gz
  12. 9469a03c94b85e010d116aeeab9614c0 19441880 Contents-amd64.gz
  13. 3d68e206d7faa3aded660dc0996054fe 19203165 Contents-armel.gz
  14. ...
[注意]注意

第 2.1.4 节 “Debian 档案库基础” 里,你能够发现我使用”suite” 和 “codename”的逻辑。“发行版”被用来同时谈及”suite” 和 “codename”.所有由档案库提供的归档 “area” 名,会被列在 “Components” 下.

顶层文件 “Release“ 的完整性,是由叫 secure apt 的加密架构来验证.

  • 加密签名文件 “Release.gpg“ 是由顶层授权文件 “Release“ 和加密的 Debian 档案库公钥创建。

  • 公开的 Debian 档案库公钥能够被植入“/etc/apt/trusted.gpg”;

  • secure APT 系统验证下载的顶层文件 “Release“ 的完整性。加密验证过程用到了”Release.gpg“文件和在”/etc/apt/trusted.gpg“里的 Debian 档案库公钥.

所有 “Packages“ 和 “Sources“ 文件的完整性是由在顶层 “Release“ 文件里的 MD5sum 值来验证。所有软件包文件的完整性由 “Packages“ 和 “Sources“ 文件里的 MD5sum 值来验证.参见 debsums(1) 和 第 2.4.2 节 “验证安装的软件包文件”.

因加密签名验证比计算 MD5sum 值消耗更多的 CPU,使用 MD5sum 值来验证每一个软件包,使用加密签名来验证顶层的 “Release“ 文件,这种方式提供 较好安全性的同时,也有比较好的性能 (参见 第 10.3 节 “数据安全基础”).

2.5.3. 档案库层的“Release”文件

[提示]提示

档案库层的“Release”文件将用作apt_preferences(5)的规则。

归档层次的 “Release“ 文件,其全部归档位置在 “/etc/apt/sources.list“中的 “deb“行中指定,如以下的 “http://deb.debian.org/debian/dists/unstable/main/binary-amd64/Release“ 或 “http://deb.debian.org/debian/dists/sid/main/binary-amd64/Release“。

  1. Archive: unstable
  2. Origin: Debian
  3. Label: Debian
  4. Component: main
  5. Architecture: amd64
[小心]小心

对于”Archive:“ 章节,系列名称(“stable“,”testing“,”unstable“, …) 用于 Debian archive ,而代号(“trusty“, “xenial“, “artful“, …) 用于 Ubuntu archive

对于部分档案库,比如说 experimentalbullseye-backports, 它们包含的软件包不会被自动安装,这是因为有额外的行,例如在 “http://deb.debian.org/debian/dists/experimental/main/binary-amd64/Release“ 里面有如下额外的一行。

  1. Archive: experimental
  2. Origin: Debian
  3. Label: Debian
  4. NotAutomatic: yes
  5. Component: main
  6. Architecture: amd64

请注意,普通的档案库没有 “NotAutomatic: yes“, 默认的 Pin-Priority 值是 500, 而对于有 “NotAutomatic: yes“的特殊档案库, 默认的 Pin-Priority 值是 1 (参见 apt_preferences(5) 和 第 2.7.3 节 “调整候选版本”).

2.5.4. 获取用于软件包的元数据

当使用 APT 工具时,如 aptitude, apt-get, synaptic, apt-file, auto-apt,我们需要更新包含 Debian 档案库信息元数据的本地拷贝。这些本地拷贝的文件名称,和在 “/etc/apt/sources.list“ 文件里面的 distribution, area, architecture 相应名称一致。 (参见 第 2.1.4 节 “Debian 档案库基础”).

  • /var/lib/apt/lists/deb.debian.org_debian_dists_<distribution>_Release

  • /var/lib/apt/lists/deb.debian.org_debian_dists_<distribution>_Release.gpg

  • /var/lib/apt/lists/deb.debian.org_debian_dists_<distribution>_<area>_binary-<architecture>_Packages

  • /var/lib/apt/lists/deb.debian.org_debian_dists_<distribution>_<area>_source_Sources

  • /var/cache/apt/apt-file/deb.debian.org_debian_dists_<distribution>_Contents-<architecture>.gz“ (apt-file)

前 4 种类型的文件是所有相关的 APT 命令共享的,并且可以通过 “apt-get update” 或 “aptitude update” 在命令行中进行更新。如果在 “/etc/apt/sources.list” 中有相应的 “deb” 行,则 “软件包” 元数据会进行更新。如果在 “/etc/apt/sources.list” 中有相应的 “deb-src” 行,则 “源代码” 元数据会进行更新。

Packages“ 和 “Sources“ 的元数据文件包含有“Filename:”字段,指向二进制和源代码包文件的位置。目前,这些软件包都统一放在”pool/“目录树下,这样可以改善跨版本发布的传输。

软件包”元数据的本地副本可以使用 aptitude 来进行交互式的搜索。专门的搜索命令 grep-dctrl(1) 可以搜索“软件包”和“源代码”元数据的本地副本。

Contents-<architecture>“元数据的本地拷贝,能够被”apt-file update“更新,它的位置和其它 4 个不同。参见 apt-file(1). (auto-apt 的 “Contents-<architecture>.gz“文件的本地拷贝默认也使用不同的位置。)

2.5.5. APT 的软件包状态

除了远程获取元数据,lenny 之后的 APT 工具还会将它在本地产生的安装状态信息保存在 “/var/lib/apt/extended_states” 中,APT 会使用它们来追踪自动安装的所有软件包。

2.5.6. aptitude 的软件包状态

除了远程获取元数据,aptitude 命令还会将它在本地产生的安装状态信息保存在 “/var/lib/aptitude/pkgstates” 中,这些信息只能被 aptitude 使用。

2.5.7. 获取的软件包的本地副本

所有通过 APT 机制远程获取的软件包都被保存在 “/var/cache/apt/archives” 中,直到它们被清除。

aptitude 的这个缓存文件清理策略,能够在”Options“ → “Preferences“下设置,也可以通过它的菜单,”Actions“下的”Clean package cache“ 或 “Clean obsolete files“ 来执行强制清理。

2.5.8. Debian 软件包文件名称

Debian 软件包文件有特定的名称结构。

表 2.15. Debian 软件包的名称结构

软件包类型名称结构
二进制软件包(亦称 deb<package-name><upstream-version>-<debian-version><architecture>.deb
用于 debian-installer 的二进制软件包(亦称 udeb<package-name><upstream-version>-<debian-version><architecture>.udeb
源代码软件包(上游源代码)<package-name><upstream-version>-<debian-version>.orig.tar.gz
1.0 源代码软件包(Debian 改变)<package-name><upstream-version>-<debian-version>.diff.gz
3.0 (quilt 补丁管理工具) 源代码软件包(Debian 改变)<package-name><upstream-version>-<debian-version>.debian.tar.gz
源代码软件包(说明)<package-name><upstream-version>-<debian-version>.dsc
[提示]提示

这里仅叙述了基本的源码包格式。更多内容请参考 dpkg-source(1)。

表 2.16. Debian 软件包名称中每一个组件可以使用的字符

名称组件可用的字符(正则表达式)存在状态
<package-name>[a-z,A-Z,0-9,.,+,-]+必需
<epoch>:[0-9]+:可选
<upstream-version>[a-z,A-Z,0-9,.,+,-,:]+必需
<debian.version>[a-z,A-Z,0-9,.,+,~]+可选
[注意]注意

你可以用 dpkg(1)提供的命令检查软件包版本, 例如., “dpkg —compare-versions 7.0 gt 7.~pre1 ; echo $?“ .

[注意]注意

debian-installer (d-i) 使用 udeb 作为它的二进制软件包的文件扩展名,而非普通的 deb。一个 udeb 软件包是从 deb 软件包中剥离了一些不必要的内容(例如文档),从而节省空间同时也放宽软件包政策的要求。debudeb 软件包会共享相同的软件包结构。“u” 表示微小。

2.5.9. dpkg 命令

dpkg(1) 是 Debian 软件包管理中最底层的工具。它非常强大,必须小心使用。

当安装名为 “<package_name>” 的软件包时,dpkg 会按照下列的顺序处理它。

  1. 解包 deb 文件(等同于 “ar -x”)

  2. 使用 debconf(1) 执行 “<package_name>.preinst

  3. 将软件包安装到系统中(等同于 “tar -x”)

  4. 使用 debconf(1) 执行 “<package_name>.postinst

debconf 系统提供带有 I18N 和 L10N (第 8 章 国际化和本地化)支持的标准化用户交互。

表 2.17. dpkg 创建的重要文件

文件内容说明
/var/lib/dpkg/info/<package_name>.conffiles列出配置文件。(使用者可修改的)
/var/lib/dpkg/info/<package_name>.list列出软件包安装的所有文件和目录
/var/lib/dpkg/info/<package_name>.md5sums列出软件包安装的文件的 MD5 哈希值
/var/lib/dpkg/info/<package_name>.preinst软件包安装之前运行的软件包脚本
/var/lib/dpkg/info/<package_name>.postinst软件包安装之后运行的软件包脚本
/var/lib/dpkg/info/<package_name>.prerm软件包移除之前运行的软件包脚本
/var/lib/dpkg/info/<package_name>.postrm软件包移除之后运行的软件包脚本
/var/lib/dpkg/info/<package_name>.config用于 debconf 系统的软件包脚本
/var/lib/dpkg/alternatives/<package_name>update-alternatives 命令使用的替代信息
/var/lib/dpkg/available所有软件包的可用性信息
/var/lib/dpkg/diversionsdpkg(1) 使用的文件移动信息,由 dpkg-divert(8) 设置
/var/lib/dpkg/statoverridedpkg(1) 使用的文件状态改变信息,由 dpkg-statoverride(8) 设置
/var/lib/dpkg/status所有软件包的状态信息
/var/lib/dpkg/status-oldvar/lib/dpkg/status” 文件的第一代备份
/var/backups/dpkg.status*第二代备份,以及“var/lib/dpkg/status”文件更旧的备份

status” 文件也被例如 dpkg(1)、“dselect update” 和 “apt-get -u dselect-upgrade” 等工具使用。

专门的搜索命令 grep-dctrl(1) 可以搜索 “status” 和 “available” 元数据的本地副本。

[提示]提示

debian 安装器环境下, udpkg 命令用于打开udeb 软件包,udpkg 命令是 dpkg 命令的一个精简版本.

2.5.10. update-alternatives 命令

Debian 系统使用 update-alternatives(1) 让用户可以不受干扰地安装多种重叠的程序。例如,如果同时安装了 vimnvi 软件包,你可以使 vi 命令选择运行 vim

  1. $ ls -l $(type -p vi)
  2. lrwxrwxrwx 1 root root 20 2007-03-24 19:05 /usr/bin/vi -> /etc/alternatives/vi
  3. $ sudo update-alternatives --display vi
  4. ...
  5. $ sudo update-alternatives --config vi
  6. Selection Command
  7. ----------------------------------------------
  8. 1 /usr/bin/vim
  9. *+ 2 /usr/bin/nvi
  10. Enter to keep the default[*], or type selection number: 1

Debian 选择系统在 “/etc/alternatives/“ 目录里通过符号链接来维持它的选择。选择进程使用”/var/lib/dpkg/alternatives/“目录里面的相应文件。

2.5.11. dpkg-statoverride 命令

当安装一个软件包时,由 dpkg-statoverride(8) 命令提供的 状态修改,是告诉dpkg(1) 对 文件 使用不同的属主或权限的一个方法。如果使用了 “--update“ 选项,并且文件存在,则该文件会被立即设置为新的属主和模式。

[小心]小心

系统管理员使用 chmodchown 命令直接修改某个软件包文件的属主或权限,将会在下次软件包升级时,被重置。

[注意]注意

本人在此使用了文件 一词,但事实上也可用于dpkg 所处理的任何文件系统对象,包括目录,设备等。

2.5.12. dpkg-divert 命令

dpkg-divert(8) 命令提供的文件转移,是迫使 dpkg(1) 将文件不安装到其默认位置,而是安装到转移 的位置。dpkg-divert 是软件包维护脚本。不建议系统管理员使用这个命令。

2.6. 从损坏的系统中恢复

当运行 unstable 系统,系统管理员会遇到从错误的软件包管理进行恢复的情形。

[小心]小心

下面的一些方法具有很高的风险。在此先对你进行警告!

2.6.1. 不兼容旧的用户配置

如果一个桌面 GUI 程序在重要的上游版本升级后变得不稳定,你应该怀疑这是旧的本地配置文件(由它创建的)所导致的。如果它在新建的用户账号下运行稳定,那么这个假设就得到了证实。(这是一个打包的 bug 并且打包者通常会避免它。)

为了恢复稳定,你应该移除相应的本地配置文件并重新启动 GUI 程序。你可能需要阅读旧的配置文件内容以便之后恢复配置信息。(别将它们删得太快了。)

2.6.2. 具有相同文件的不同软件包

文档级的软件包管理系统,比如说 aptitude(8) 或 apt-get(1), 使用软件包依赖,当出现相同文件时,不会尝试去安装软件包。(参见 第 2.1.6 节 “软件包依赖关系”).

软件包维护者的错误,或者系统管理员配置了不一致的档案库混合源,(参见 第 2.7.2 节 “混合源档案库中的软件包”),都会出现不正确的软件包依赖情况。如果在出现相同文件的情况下,你通过 aptitude(8) 或 apt-get(1) 安装软件包,dpkg(1) 在对软件包解包时,确定会给调用程序返回错误,并不会覆盖已经存在的文件。

[小心]小心

使用第三方软件包会导致重大的系统风险,因为其通过使用 root 权限运行维护者脚本能够对你的系统做任何事。dpkg(1) 命令只防止解包时的覆盖行为。

可以先通过删除旧的令人讨厌的软件包,<old-package>,来解决这类错误的安装问题。

  1. $ sudo dpkg -P <old-package>

2.6.3. 修复损坏的软件包脚本

当软件包脚本中的一个命令由于某些原因返回错误,脚本也将由于错误而退出,软件包管理系统忽略它们的行为,并导致部分安装的软件包。当一个软件包在它的删除脚本中有错误时,该软件包将会成为不可能删除的软件包,处理这些问题,都会变得相当棘手。

对于 “<package_name>” 的软件包脚本问题,你应该查看下列的软件包脚本。

  • /var/lib/dpkg/info/<package_name>.preinst

  • /var/lib/dpkg/info/<package_name>.postinst

  • /var/lib/dpkg/info/<package_name>.prerm

  • /var/lib/dpkg/info/<package_name>.postrm

使用下列的方法,以 root 编辑损坏的软件包脚本。

  • 在行首添加 “#” 可以禁用出错的行

  • 在出错行的行尾添加 “|| true” 可以强制返回成功

使用下列命令来配置所有部分安装的软件包。

  1. # dpkg --configure -a

2.6.4. 使用 dpkg 命令进行救援

因为 dpkg 是非常底层的软件包工具,它可以在很糟糕的情况下进行工作,例如无法启动系统且没有网络连接。让我们假定 foo 软件包损坏了,并且需要更换。

你可以在软件包缓存目录:“/var/cache/apt/archives/” 中找到旧的 foo 软件包的无 bug 版本。(如果找不到,你可以从档案库 https://snapshot.debian.org/ 中下载它,或从具有软件包缓存功能的机器中拷贝它。)

如果你能够启动系统,你可以通过下列命令来安装它。

  1. # dpkg -i /path/to/foo_<old_version>_<arch>.deb
[提示]提示

如果你系统损坏较小,你也可以使用更高层的 APT 系统来降级整个系统,就像 第 2.7.10 节 “紧急降级” 中做的那样。

如果你的系统无法从硬盘启动,你应该寻找其它方式来启动它。

  1. 使用 Debian 安装光盘以救援模式启动系统。

  2. 将硬盘上无法启动的系统挂载到 “/target”。

  3. 通过下列命令安装旧版本的 foo 软件包。

  1. # dpkg --root /target -i /path/to/foo_<old_version>_<arch>.deb

即使位于硬盘上的 dpkg 命令已损坏,该命令依旧可以执行。

[提示]提示

任何由硬盘、live GNU/Linux CD、可启动的 USB 驱动或网络启动上的另一系统启动的 GNU/Linux 系统到可以类似地用来救援损坏的系统。

如果由于依赖问题,无法用这种方式安装软件包,并且你真的必须真么做,你可以使用 dpkg 的 “--ignore-depends”、“--force-depends” 和其它选项来无视依赖。如果你这么做了,之后你必须认真努力地修复依赖关系。更多细节参见 dpkg(8)。

[注意]注意

如果你的系统严重损坏了,你应该将系统完整备份到一个安全的地方(参见 第 10.2 节 “备份和恢复”)并进行一次全新的安装。这是耗时较少且效果较好的办法。

2.6.5. 恢复软件包选择数据

如果 “/var/lib/dpkg/status” 因为某种原因出现错误,Debian 系统会丢失软件包选择数据并受到严重影响。寻找位于 “/var/lib/dpkg/status-old” 或 “/var/backups/dpkg.status.*” 中旧的 “/var/lib/dpkg/status” 文件。

给 “/var/backups/” 分配一个单独的分区是一个好习惯,因为这个目录包含了许多重要的系统数据。

对于严重的损坏,我建议备份系统后重新安装。即使失去 “/var/” 中的所有数据,你依旧可以从 “/usr/share/doc/” 目录恢复一些信息来引导你进行新的安装。

重新安装最小(桌面)系统。

  1. # mkdir -p /path/to/old/system

将旧系统挂载到 “/path/to/old/system/”。

  1. # cd /path/to/old/system/usr/share/doc
  2. # ls -1 >~/ls1.txt
  3. # cd /usr/share/doc
  4. # ls -1 >>~/ls1.txt
  5. # cd
  6. # sort ls1.txt | uniq | less

然后你就可以根据软件包名称来进行安装了。(可能会有一些非软件包名称,例如 “texmf”。)

2.7. 软件包管理技巧

2.7.1. 如何挑选 Debian 软件包

你可以根据 aptitude 这个包管理工具中的软件包描述或者是任务面板下的列表信息,来查找你所需要的软件包。

当遇到2个以上的类似的软件包时,先前没有经过反复的尝试,你不知道安装哪一个的时候,应该用常识来判断。我认为以下几点是首选的软件包应该具有的特征。

  • 重要性:是 > 否

  • 类型:main > contrib > non-free

  • 优先级:需要 > 重要 > 标准 > 可选 > 额外

  • 任务:在任务下有软件包的列表信息,例如 “桌面环境”

  • 软件包是被与之有依赖关系的软件包所选择的(例如 python2.4 依赖 python

  • 流行度:在投票或者安装指数上有着更高的分数

  • 更新日志:维护者经常的更新

  • BTS (缺陷跟踪系统):没有 RC 级别的缺陷(没有危险、重大严重的缺陷)

  • BTS (缺陷跟踪系统):有维护者对缺陷报告反馈

  • BTS (缺陷跟踪系统): 有着更多的近期修复的 bug 数目

  • BTS (缺陷跟踪系统):遗留的非严重(non-wishlist)缺陷数量较少

Debian 是一个使用分布式开发模式的志愿项目,它的档案库包含了许多不同关注点和不同质量的软件包。你必须做出自己的选择。

2.7.2. 混合源档案库中的软件包

[小心]小心

从混合源档案库中安装软件包是不被 Debian 官方发行版所支持的,除了官方支持的档案库的特殊组合以外,例如 stablesecurity updatesbullseye-updates

这里有一个列子,在原有只跟踪 testing 的场景,操作包含在 unstable 里发现的新的上游软件包版本。

  1. 临时更改 “/etc/apt/sources.list“ 文件,使之指向单一的 “unstable“ 发行版路径。

  2. 运行 “aptitude update“ 命令。

  3. 运行 “aptitude install <package-name>“ 命令。

  4. 恢复到原始 “/etc/apt/sources.list“ 文件,使之指向 testing 路径。

  5. 运行 “aptitude update“ 命令。

使用这个手工方法,你不需要创建 “/etc/apt/preferences“ 文件,也不需要担心 apt-pinning。但这个方法仍然是非常麻烦的。

[小心]小心

当使用混合档案源的时候,因为 Debian 不会确保软件之间的兼容性,所以你必须自己去解决兼容性问题。如果软件之间存在不兼容性,系统可能会损坏。你必须能够判断这些操作所需的技术要求。使用任意混合的档案源是完全可选的操作,我并不鼓励你去使用它。

从不同的档案库中安装软件包的一般规则如下。

  • 非二进制软件包 (“Architecture: all“) 的安装是更保险的

    • 文档软件包:没有特别的要求

    • 解释程序的软件包:兼容的解释器必须是可用的

    • 二进制软件包 (non “Architecture: all“)通常会面临很多障碍,它的安装不保险的

    • 库文件版本的兼容性(包括 “libc“)

    • 与之相关的有用的程序版本的兼容性

      • 内核 ABI 的兼容性
    • C++ ABI 的兼容性

[注意]注意

为了使软件包的安装变得更保险 ,一些商业的非自由的二进制程序包可能会提供完整的静态链接库。你还是应该检查 ABI 的兼容性问题等等。

[注意]注意

为避免短期出现坏的软件包,从非官方支持的档案库安装二进制软件包通常是一个坏注意。即使你在使用 apt-pinning 情况下,也是这样的。(参见 第 2.7.3 节 “调整候选版本”).你应当考虑使用 chroot 或类似技术(参见 第 9.10 节 “虚拟化系统”)来运行不同档案库的程序。

2.7.3. 调整候选版本

没有 “/etc/apt/preferences“ 文件,APT 系统使用版本字符串来选择最新的可用版本作为 候选版本。这是通常的状态,也是 APT 系统最推荐的使用方法。所有官方支持的档案库集合,并不要求 “/etc/apt/preferences“ 文件,因此,一些不应当被作为自动更新源的软件包,被标记为 NotAutomatic,并被适当处理。

[提示]提示

版本字符串的比较规则可以被验证,例子如下,”dpkg —compare-versions ver1.1 gt ver1.1~1; echo $?“ (参见 dpkg(1))。

如果经常从混合源档案库中安装软件包 (参见第 2.7.2 节 “混合源档案库中的软件包”), 你可以通过创建 “/etc/apt/preferences“ 文件并且在其中写入关于调整候选版本的软件包选取规则的合适条目 (如apt_preferences(5) 中所示)来自动化这些复杂的操作。这被称为 apt-pinning

[警告]警告

新手用 apt-pinning 命令会造成比较大的问题。你必须避免使用这个命令除非确实需要它。

[小心]小心

当使用 apt-pinning 命令时,因为 Debian 不会确保软件之间的兼容性,所以你必须自己确认其兼容性。apt-pinning 是完全可选的操作,我并不建议去使用它。

[小心]小心

档案库层级的 Release 文件 (参见 第 2.5.3 节 “档案库层的“Release”文件”) 使用 apt_preferences(5) 的规则.对于 Debian 通用档案库Debian 安全档案库,apt-pinning 只在 “suite” 名下工作。(这点和 Ubuntu 档案库不同.)例如,你在 “/etc/apt/preferences“ 文件里面,可以使用”Pin: release a=unstable“ ,但不能使用 “Pin: release a=sid“.

[小心]小心

当使用非 Debian 的档案库作为 apt-pinning 的一部分时,你应该检查它们的用途和可信度。例如,Ubuntu 和 Debian 是不能混在一起的。

[注意]注意

即使不创建 “/etc/apt/preferences“ 文件,在不用 apt-pinning 命令的情况下,你也可以进行相当复杂的系统工作 (参见第 2.6.4 节 “使用 dpkg 命令进行救援”第 2.7.2 节 “混合源档案库中的软件包”)。

如下是关于 apt-pinning 技术的简化说明。

可用的软件包源在 “/etc/apt/sources.list“ 文件里面定义,APT 系统从可用的软件包源里面选择 Pin-Priority 值最大的,作为升级 软件包的候选版本.如果一个软件包的 Pin-Priority 大于 1000,这个版本限制为只能 升级,关闭了软件包降级功能 (参见 第 2.7.10 节 “紧急降级”).

每个软件包的 Pin-Priority 值是在 “/etc/apt/preferences“ 文件中的 “Pin-Priority” 条目中定义或者是使用它的默认值。

表 2.18. 用于 apt-pinning 技术的值得注意的 Pin-Priority 值列表。

Pin-Priorityapt-pinning 对软件包的影响
1001安装该软件包,即使是一个降级软件包的指令
990用作目标发行版档案库的默认值
500用作常规档案库的默认值
100用于 NotAutomaticButAutomaticUpgrades 档案库的默认值
100用于已安装软件包
1用于 NotAutomatic 档案库的默认值
-1即使被推荐,也绝不安装这个软件包

目标发行版档案库可以通过以下几种方法来设置。

  • /etc/apt/apt.conf“ 配置文件中写入 “APT::Default-Release "stable";

  • 命令行选项,例如: “apt-get install -t testing some-package

NotAutomaticButAutomaticUpgrades 的档案是由档案库服务器上档案层级的 Release 文件来设置,(参见 第 2.5.3 节 “档案库层的“Release”文件”),同时包含”NotAutomatic: yes“ 和 “ButAutomaticUpgrades: yes“.而 NotAutomatic 档案也是由档案库服务器上的档案层级的 Release 文件来设置,但只包含 “NotAutomatic: yes“.

来自众多档案源的<软件包>的 apt-pinning 情况可以通过 “apt-cache policy <package>“ 命令显示。

  • Package pin:“ 开头的行,列出了软件包版本的 pin ,如果 <package> 相关的 pin 已经定义, 例如, “Package pin: 0.190“.

  • 没有 “Package pin:“ 的行存在,如果没有 <package> 相关的定义。

  • 与 <package> 相关的 Pin-Priority 值列在所有版本字符串的右边,比如,”0.181 700“.

  • 0“ 是列在所有版本字符串的右边,如果没有 <package> 相关的定义。例如, “0.181 0“.

  • 档案库 (在 “/etc/apt/preferences“ 文件作为”Package: *“定义) 的 Pin-Priority 值,列在所有档案库路径的左边,例如,”100 http://deb.debian.org/debian/ bullseye-backports/main Packages“.

2.7.4. 更新和向后移植

bullseye-updatesbackports.debian.org 档案库提供了stable (bullseye) 发行版的更新软件包。

为了去使用这些档案库,你需要在 “/etc/apt/sources.list“ 文件里写入如下所示的档案库列表。

  1. deb http://deb.debian.org/debian/ bullseye main contrib non-free
  2. deb http://security.debian.org/ bullseye/updates main contrib
  3. deb http://deb.debian.org/debian/ bullseye-updates main contrib non-free
  4. deb http://deb.debian.org/debian/ bullseye-backports main contrib non-free

并不需要在 “/etc/apt/preferences“ 文件中显式设置Pin-Priority值. 当新的包可用时,默认配置提供了更合理的更新 (请见 第 2.5.3 节 “档案库层的“Release”文件”).

  • 所有已安装的旧软件包都可以通过 bullseye-updates 档案库升级到新软件包。

  • 只有从 bullseye-backports 档案库中手动安装的旧软件包才会通过 bullseye-backports 档案库升级到新软件包。

当你想要从 bullseye-backports 档案库中手动的安装一个名叫 “<package-name>“ 的软件及其依赖包的时候,你应该在目标档案库之前加一个 “-t” 参数。

  1. $ sudo apt-get install -t bullseye-backports <package-name>

2.7.5. 阻止推荐的软件包的安装

如果不想要引入推荐的特定软件包,你必须创建 “/etc/apt/preferences“ 文件并且像如下所示的那样在文件的顶部明确列出这些软件包。

  1. Package: <package-1>
  2. Pin: version *
  3. Pin-Priority: -1
  4. Package: <package-2>
  5. Pin: version *
  6. Pin-Priority: -1

2.7.6. 使用带有 unstable 软件包的 testing 版本

如下是一个关于 apt-pinning 技术的例子,当使用 testing的时候,实现 unstable 中的特定的较新的上游版本软件包的日常升级。你应该按如下所示的在 “/etc/apt/sources.list“ 文件中列出所有需要的档案库。

  1. deb http://deb.debian.org/debian/ testing main contrib non-free
  2. deb http://deb.debian.org/debian/ unstable main contrib non-free
  3. deb http://security.debian.org/ testing/updates main contrib

按如下所示的设置 “/etc/apt/preferences“ 文件。

  1. Package: *
  2. Pin: release a=unstable
  3. Pin-Priority: 100

当想要在此配置下从 unstable 档案库中安装 “<package-name>“ 软件及它的依赖包时,你执行带有 “-t“ 选项 (unstable 的 Pin-Priority 值变为 990) 的转换目标发行版的命令。

  1. $ sudo apt-get install -t unstable <package-name>

在此配置下,执行 “apt-get update“ 和 “apt-get dist-upgrade“(或者 “aptitude safe-upgrade“ 和 “aptitude full-upgrade“) 命令,会从 testing 档案库升级那些从 testing 档案库安装的软件包并且从 unstable 档案库升级那些从 unstable 档案库中安装的软件包。

[小心]小心

小心不要去移除 “/etc/apt/sources.list“ 文件中的 “testing“ 档案库。如果文件中没有 “testing“ ,APT 系统会使用更加新的 unstable 档案库升级软件包。

[提示]提示

我通常会在上述操作后,马上注释掉 “/etc/apt/sources.list“ 文件中的 “unstable“ 档案库记录。这避免了因为处理 “/etc/apt/sources.list“ 文件中的众多记录而造成的升级缓慢虽然同时也阻止了那些从 unstable 档案库中安装的软件包通过 unstable 升级。

[提示]提示

如果 “/etc/apt/preferences“ 文件中 “Pin-Priority: 1“ 替代了 “Pin-Priority:100“,即使 “/etc/apt/sources.list“ 文件中的 “testing“ 记录被删除了,Pin-Priority 值为 100 的已安装软件包也不会通过 unstable 档案库升级。

如果你希望自动跟踪 unstable 里某些特殊的软件包,而在安装时不再使用初始化选项 “-t unstable“ , 你必须创建 “/etc/apt/preferences“ 文件,并在该文件顶部按下面的方式清晰的列出所有那些软件包。

  1. Package: <package-1>
  2. Pin: release a=unstable
  3. Pin-Priority: 700
  4. Package: <package-2>
  5. Pin: release a=unstable
  6. Pin-Priority: 700

如下是为每个特定的软件包设置 Pin-Priority 值。例如,为了使用最新的 unstable 的英文版 “Debian Reference”,你应该在 “/etc/apt/preferences“ 文件中写入以下条目。

  1. Package: debian-reference-en
  2. Pin: release a=unstable
  3. Pin-Priority: 700
  4. Package: debian-reference-common
  5. Pin: release a=unstable
  6. Pin-Priority: 700
[提示]提示

即使你使用的是 stable 档案库,apt-pinning 技术仍然是有效的。根据我以前的经验,从 unstable 档案库安装的文档包一直是安全的。

2.7.7. 使用带有 experimental 软件包的 unstable 版本

这是使用apt-pinning 的另一个示例,该示例主要使用unstable源,但包含了experimental源, 该源可用于安装上游更新的软件包 . 需要包含在”/etc/apt/sources.list“ 文件中的列表如下:

  1. deb http://deb.debian.org/debian/ unstable main contrib non-free
  2. deb http://deb.debian.org/debian/ experimental main contrib non-free
  3. deb http://security.debian.org/ testing/updates main contrib

由于experimental源是 非自动(NotAutomatic)的源 (参见 第 2.5.3 节 “档案库层的“Release”文件”),其默认的Pin-Priority值 被设置为1 (<<100) . 并不需要在”/etc/apt/preferences“文件中设置Pin-Priority值,只需要指定 experimental 源,除非你需要在下次更新时自动升级时更新特定软件包.

2.7.8. 自动下载和升级软件包

apt 软件包有自己的 cron 脚本 “/etc/cron.daily/apt” ,它支持自动下载软件包。可以安装 unattended-upgrades 软件包来增强这个脚本,使它能够自动升级软件包。可以通过 “/etc/apt/apt.conf.d/02backup” 和 “/etc/apt/apt.conf.d/50unattended-upgrades” 中的参数来进行自定义,相关说明位于 “/usr/share/doc/unattended-upgrades/README” 中。

unattended-upgrades 软件包主要用于 stable 系统的安全更新。如果自动升级损坏 stable 系统的风险小于被入侵者利用已被安全更新修复的安全漏洞,你应该考虑使用自动更新,配置参数如下。

  1. APT::Periodic::Update-Package-Lists "1";
  2. APT::Periodic::Download-Upgradeable-Packages "1";
  3. APT::Periodic::Unattended-Upgrade "1";

如果你运行的是 unstable 系统,你应该不会想要使用自动更新,因为它肯定会在某天损坏系统。即使位于这样的 unstable 情况下,你可能依旧想提前下载软件包以节省交互式升级的时间,其配置参数如下。

  1. APT::Periodic::Update-Package-Lists "1";
  2. APT::Periodic::Download-Upgradeable-Packages "1";
  3. APT::Periodic::Unattended-Upgrade "0";

2.7.9. 限制 APT 的下载带宽

如果你想限制 APT 的下载带宽到 800Kib/sec(=100KiB/sec),你应该像下面那样设置 APT 的配置参数。

  1. APT::Acquire::http::Dl-Limit "800";

2.7.10. 紧急降级

[小心]小心

降级在 Debian 设计上就不被官方支持。仅仅是在紧急恢复过程中需要做的一部分工作。尽管憎恨这种情形,但降级在很多场景下工作得也不错。对于重要系统,你应当在恢复操作后备份所有重要数据,并从零开始重新安装一个新的系统。

你可以通过控制候选版本从新的档案库降级到旧的档案库(参见 第 2.7.3 节 “调整候选版本”),从而使损坏的系统恢复。下面是一种懒惰的方法,可以避免许多冗长的 “dpkg -i <broken-package>_<old-version>.deb” 命令(参见 第 2.6.4 节 “使用 dpkg 命令进行救援”)。

搜索 “/etc/apt/sources.list” 文件中像下面那样使用 unstable 的行。

  1. deb http://deb.debian.org/debian/ sid main contrib non-free

使用下面的行替换它,从而改为使用 testing

  1. deb http://deb.debian.org/debian/ bookworm main contrib non-free

按如下所示的设置 “/etc/apt/preferences“ 文件。

  1. Package: *
  2. Pin: release a=testing
  3. Pin-Priority: 1010

运行 “apt-get update; apt-get dist-upgrade” 使整个系统的软件包强制降级。

在紧急降级后,移除 “/etc/apt/preferences” 这个特殊的文件。

[提示]提示

这是一个好方法,移除(不是清除!)尽可能多地软件包,来减少依赖问题。你可能需要手动移除和安装一些软件包来使系统降级。需要特别注意 Linux 内核、引导程序、udev、PAM、APT 和网络相关的软件包以及它们的配置文件。

2.7.11. 上传软件包的是谁?

尽管 “/var/lib/dpkg/available” 和 “/usr/share/doc/package_name/changelog” 中列出的维护者姓名提供了关于“软件包运作的幕后者是谁”这一问题的一些信息,但软件包的实际上传者依旧不明。devscripts 软件包中的 who-uploads(1) 可以识别 Debian 源软件包的实际上传者。

2.7.12. equivs 软件包

如果你从源代码编译了一个程序来代替 Debian 软件包,最好将它做成一个真正的本地 Debian 软件包(*.deb)并使用私人档案库。

如果你选择从源代码编译一个程序并将它安装到 “/usr/local”,你可能需要使用 equivs 作为最后步骤来满足缺失的软件包依赖。

  1. Package: equivs
  2. Priority: optional
  3. Section: admin
  4. Description: Circumventing Debian package dependencies
  5. This package provides a tool to create trivial Debian packages.
  6. Typically these packages contain only dependency information, but they
  7. can also include normal installed files like other packages do.
  8. .
  9. One use for this is to create a metapackage: a package whose sole
  10. purpose is to declare dependencies and conflicts on other packages so
  11. that these will be automatically installed, upgraded, or removed.
  12. .
  13. Another use is to circumvent dependency checking: by letting dpkg
  14. think a particular package name and version is installed when it
  15. isn't, you can work around bugs in other packages' dependencies.
  16. (Please do still file such bugs, though.)

2.7.13. 移植一个软件包到 stable 系统

对于部分升级的 stable 系统,使用源软件包在运行环境中重新构建一个软件包是不错的选择。这可以避免因为依赖关系导致大量软件包升级。

stable 系统的 “/etc/apt/sources.list” 文件中添加下列条目。

  1. deb-src http://deb.debian.org/debian unstable main contrib non-free

如下安装编译所需的软件包并下载源软件包。

  1. # apt-get update
  2. # apt-get dist-upgrade
  3. # apt-get install fakeroot devscripts build-essential
  4. # apt-get build-dep foo
  5. $ apt-get source foo
  6. $ cd foo*

如果需要向后移植,可以从 backport 的软件包中更新一些工具链软件包,例如 dpkgdebhelper

执行下列命令。

  1. $ dch -i

更新软件包版本,例如在 “debian/changelog” 中附加一个 “+bp1

像下面那样构建软件包并将它们安装到系统中。

  1. $ debuild
  2. $ cd ..
  3. # debi foo*.changes

2.7.14. 用于 APT 的代理服务器

因为镜像整个 Debian 档案库的子区会浪费硬盘和网络带宽,当你管理许多 LAN 上的系统时,为 APT 部署一个本地代理服务器是个好主意。APT 可以通过配置来使用通用 web(http)代理服务器,例如 squid(参见 第 6.10 节 “其它网络应用服务”),细节参见 apt.conf(5) 和 “/usr/share/doc/apt/examples/configure-index.gz”。环境变量 “$http_proxy 会覆盖 “/etc/apt/apt.conf” 文件中设置的代理服务器。

这里有一些 Debian 档案库的专用代理工具。你应该在使用它们之前检查 BTS。

表 2.19. Debian 档案库的专用代理工具

软件包流行度大小说明
approxV:0, I:06317缓存 Debian 档案库文件的代理服务器(已编译的 OCaml 程序)
apt-cacherV:0, I:0289为 Debian 软件包和源代码文件进行缓存代理(Perl 程序)
apt-cacher-ngV:5, I:51488分发软件包的缓存代理(C++ 编译的程序)
[小心]小心

当 Debian 重构它的档案库结构时,这些专用的代理工具往往需要软件包维护者重写代码,并可能在一段时间内无法使用。另一方面,通用 web (http) 代理服务器更强健并且更容易应对这种改变。

2.7.15. 小型公共软件包档案库

[提示]提示

手动建立软件仓库是极其复杂的。有数个软件仓库管理工具可供用户选用。网上有一个 详尽的列表 可供参阅。

下面是一个建立小型公共软件包档案库的示例,兼容了 secure APT 系统(参见 第 2.5.2 节 “顶层“Release”文件及真实性”)。让我们进行一些假定。

  • 账号名:“foo

  • 主机名:“www.example.com

  • 所需软件包:apt-utilsgnupg 和其它软件包

  • URL: “http://www.example.com/~foo/“ ( → “/home/foo/public_html/index.html“)

  • 软件包架构:“amd64

在该服务器上使用如下方式为 Foo 创建一个 APT 源钥匙对。

  1. $ ssh foo@www.example.com
  2. $ gpg --gen-key
  3. ...
  4. $ gpg -K
  5. ...
  6. sec 1024D/3A3CB5A6 2008-08-14
  7. uid Foo (ARCHIVE KEY) <foo@www.example.com>
  8. ssb 2048g/6856F4A7 2008-08-14
  9. $ gpg --export -a 3A3CB5A6 >foo.public.key

公布 “foo.public.key“文件,即公钥 ID 为 “3A3CB5A6“的源公钥文件,该文件可用于 Foo 源的发布

使用如下方式创建一个名为”Origin: Foo”的源目录树。

  1. $ umask 022
  2. $ mkdir -p ~/public_html/debian/pool/main
  3. $ mkdir -p ~/public_html/debian/dists/unstable/main/binary-amd64
  4. $ mkdir -p ~/public_html/debian/dists/unstable/main/source
  5. $ cd ~/public_html/debian
  6. $ cat > dists/unstable/main/binary-amd64/Release << EOF
  7. Archive: unstable
  8. Version: 4.0
  9. Component: main
  10. Origin: Foo
  11. Label: Foo
  12. Architecture: amd64
  13. EOF
  14. $ cat > dists/unstable/main/source/Release << EOF
  15. Archive: unstable
  16. Version: 4.0
  17. Component: main
  18. Origin: Foo
  19. Label: Foo
  20. Architecture: source
  21. EOF
  22. $ cat >aptftp.conf <<EOF
  23. APT::FTPArchive::Release {
  24. Origin "Foo";
  25. Label "Foo";
  26. Suite "unstable";
  27. Codename "sid";
  28. Architectures "amd64";
  29. Components "main";
  30. Description "Public archive for Foo";
  31. };
  32. EOF
  33. $ cat >aptgenerate.conf <<EOF
  34. Dir::ArchiveDir ".";
  35. Dir::CacheDir ".";
  36. TreeDefault::Directory "pool/";
  37. TreeDefault::SrcDirectory "pool/";
  38. Default::Packages::Extensions ".deb";
  39. Default::Packages::Compress ". gzip bzip2";
  40. Default::Sources::Compress "gzip bzip2";
  41. Default::Contents::Compress "gzip bzip2";
  42. BinDirectory "dists/unstable/main/binary-amd64" {
  43. Packages "dists/unstable/main/binary-amd64/Packages";
  44. Contents "dists/unstable/Contents-amd64";
  45. SrcPackages "dists/unstable/main/source/Sources";
  46. };
  47. Tree "dists/unstable" {
  48. Sections "main";
  49. Architectures "amd64 source";
  50. };
  51. EOF

通过 dupload,你可以自动重复更新你服务器系统上的 APT 档案库内容。

当 “~/.dupload.conf” 包含如下内容时,在客户端执行 “dupload -t foo changes_file” 将所有的软件包文件放入 “~foo/public_html/debian/pool/main/”。

  1. $cfg{'foo'} = {
  2. fqdn => "www.example.com",
  3. method => "scpb",
  4. incoming => "/home/foo/public_html/debian/pool/main",
  5. # The dinstall on ftp-master sends emails itself
  6. dinstall_runs => 1,
  7. };
  8. $cfg{'foo'}{postupload}{'changes'} = "
  9. echo 'cd public_html/debian ;
  10. apt-ftparchive generate -c=aptftp.conf aptgenerate.conf;
  11. apt-ftparchive release -c=aptftp.conf dists/unstable >dists/unstable/Release ;
  12. rm -f dists/unstable/Release.gpg ;
  13. gpg -u 3A3CB5A6 -bao dists/unstable/Release.gpg dists/unstable/Release'|
  14. ssh foo@www.example.com 2>/dev/null ;
  15. echo 'Package archive created!'";

dupload(1)触发postupload钩子脚本,该脚本为每次上传创建软件包文件.

你可以通过下面的方法将这个小型公共档案库添加到你客户端系统的 apt 源中。

  1. $ sudo bash
  2. # echo "deb http://www.example.com/~foo/debian/ unstable main" \
  3. >> /etc/apt/sources.list
  4. # apt-key add foo.public.key
[提示]提示

如果档案库位于本地文件系统中,你可以使用 “deb file:///home/foo/debian/ …”。

2.7.16. 记录和复制系统配置

你可以通过下面命令建立软件包和 debconf 选择状态的本地副本。

  1. # dpkg --get-selections '*' > selection.dpkg
  2. # debconf-get-selections > selection.debconf

这里,“*” 使 “selection.dpkg” 也包含 “purge” 的软件包。

你可以将这两个文件移动到另一个电脑,并通过下列命令安装它们。

  1. # dselect update
  2. # debconf-set-selections < myselection.debconf
  3. # dpkg --set-selections < myselection.dpkg
  4. # apt-get -u dselect-upgrade # or dselect install

如果你需要管理一个集群中的许多服务器,并且它们的配置几乎相同,你应该考虑使用专门的软件包,例如 fai 来管理整个系统。

2.7.17. 转换或安装一个外来的二进制软件包

alien(1) 可以将 Red Hat 的 rpm、Stampede 的 slp、Slackware 的 tgz 和 Solaris 的 pkg 二进制软件包文件格式转换为 Debian 的 deb 软件包。如果你想使用来自另一个发行版的软件包,你可以使用 alien 转换并安装它。alien 也支持 LSB 软件包。

[警告]警告

不应该用 alien(1) 来替代必要的系统软件包,例如 sysvinitlibc6libpam-modules 等等。实际上,alien(1) 应该只用于 non-free 中仅提供二进制文件的软件包,并且它们应该兼容 LSB 或被静态链接。对于自由软件,你应该使用它们的源软件包来制作一个真正的 Debian 软件包。

2.7.18. 不使用 dpkg 解压软件包

在任何的 Unix-like 环境中都可以不使用 dpkg(1),而使用标准的 ar(1) 和 tar(1) 来解压 “dpkg*.deb” 软件包。

  1. # ar x /path/to/dpkg_<version>_<arch>.deb
  2. # ls
  3. total 24
  4. -rw-r--r-- 1 bozo bozo 1320 2007-05-07 00:11 control.tar.gz
  5. -rw-r--r-- 1 bozo bozo 12837 2007-05-07 00:11 data.tar.gz
  6. -rw-r--r-- 1 bozo bozo 4 2007-05-07 00:11 debian-binary
  7. # mkdir control
  8. # mkdir data
  9. # tar xvzf control.tar.gz -C control
  10. # tar xvzf data.tar.gz -C data

其它 “*.deb” 软件包的内容,可以使用 dpkg-deb(1) 命令解压来获得,和上面例子中获取“dpkg*.deb” 软件包内容的方法类似;或像上面那样使用标准的 ar(1) 命令和新版的 GNU 命令 tar(1),该 tar(1) 命令支持 xz(1) 解压功能,和上面的解压类似。

你也可以使用 mc 命令来浏览软件包内容。

2.7.19. 更多关于软件包管理的文档

你可以从下面的文档中了解软件包管理的更多信息。