第 2 章。 Debian 软件包管理

目录

2.1. Debian 软件包管理先决条件
2.1.1. 软件包配置
2.1.2. 基本预防措施
2.1.3. 与永久升级共存
2.1.4. Debian 归档库基础知识
2.1.5. 软件包依赖关系
2.1.6. 软件包管理事件流
2.1.7. 软件包管理故障的初步响应
2.2. 基本软件包管理操作
2.2.1. apt-get / apt-cacheaptitude
2.2.2. 使用命令行进行基本软件包管理操作
2.2.3. aptitude 的交互式使用
2.2.4. aptitude 的快捷键绑定
2.2.5. aptitude 下的软件包视图
2.2.6. aptitude 的搜索方法选项
2.2.7. aptitude 正则表达式公式
2.2.8. aptitude 的依赖关系解析
2.2.9. 软件包活动日志
2.3. aptitude 操作示例
2.3.1. 使用正则表达式匹配软件包名称列出软件包
2.3.2. 使用正则表达式匹配浏览
2.3.3. 彻底清除已删除的软件包
2.3.4. 整理自动/手动安装状态
2.3.5. 系统范围升级
2.4. 高级软件包管理操作
2.4.1. 使用命令行进行高级软件包管理操作
2.4.2. 已安装软件包文件的验证
2.4.3. 软件包问题保障
2.4.4. 在软件包元数据上搜索
2.5. Debian 软件包管理内部原理
2.5.1. 归档库元数据
2.5.2. 顶层 “Release” 文件和真实性
2.5.3. 归档库级别 “Release” 文件
2.5.4. 获取软件包的元数据
2.5.5. APT 的软件包状态
2.5.6. aptitude 的软件包状态
2.5.7. 已获取软件包的本地副本
2.5.8. Debian 软件包文件名
2.5.9. dpkg 命令
2.5.10. update-alternative 命令
2.5.11. dpkg-statoverride 命令
2.5.12. dpkg-divert 命令
2.6. 从损坏的系统恢复
2.6.1. 与旧用户配置不兼容
2.6.2. 具有重叠文件的不同软件包
2.6.3. 修复损坏的软件包脚本
2.6.4. 使用 dpkg 命令救援
2.6.5. 恢复软件包选择数据
2.7. 软件包管理技巧
2.7.1. 如何选择 Debian 软件包
2.7.2. 来自混合归档库源的软件包
2.7.3. 调整候选版本
2.7.4. 更新和 Backports
2.7.5. 阻止由 “Recommends” 安装的软件包
2.7.6. 跟踪 testing,同时使用来自 unstable 的一些软件包
2.7.7. 跟踪 unstable,同时使用来自 experimental 的一些软件包
2.7.8. 软件包的自动下载和升级
2.7.9. 限制 APT 的下载带宽
2.7.10. 紧急降级
2.7.11. 谁上传了软件包?
2.7.12. equivs 软件包
2.7.13. 将软件包移植到 stable 系统
2.7.14. APT 的代理服务器
2.7.15. 小型公共软件包归档库
2.7.16. 记录和复制系统配置
2.7.17. 转换或安装 alien 二进制软件包
2.7.18. 在没有 dpkg 的情况下提取软件包
2.7.19. 更多关于软件包管理的阅读材料
[Note] 注意

本章编写时假设最新的稳定版本代号为:squeeze

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

Debian 归档库许多远程镜像站点 提供,可通过 HTTP 和 FTP 方法访问。它也可以作为 CD-ROM/DVD 提供。

Debian 软件包管理系统,在正确使用时,允许用户从归档库安装一致的二进制软件包集到系统中。目前,amd64 架构有 37617 个软件包可用。

Debian 软件包管理系统拥有悠久的历史,并且为前端用户程序和后端归档库访问方法提供了许多选择。目前,我们推荐以下内容。

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

软件包 popcon 大小 描述
apt http://qa.debian.org/popcon.php?package=apt 3072 高级软件包工具 (APT),dpkg 的前端,提供 “http”、“ftp” 和 “file” 归档库访问方法(包括 apt-get/apt-cache 命令)
aptitude http://qa.debian.org/popcon.php?package=aptitude 12575 基于交互式终端的软件包管理器,带有 aptitude(8)
update-manager-gnome http://qa.debian.org/popcon.php?package=update-manager-gnome 1266 GNOME 应用程序,使用 update-manager(8) 管理软件更新
tasksel http://qa.debian.org/popcon.php?package=tasksel 188 用于在 Debian 系统上选择任务进行安装的工具(APT 的前端)
unattended-upgrades http://qa.debian.org/popcon.php?package=unattended-upgrades 252 APT 的增强软件包,用于启用安全升级的自动安装
dselect http://qa.debian.org/popcon.php?package=dselect 2376 基于终端的软件包管理器(以前的标准,APT 和其他旧访问方法的前端)
dpkg http://qa.debian.org/popcon.php?package=dpkg 5824 Debian 的软件包管理系统
synaptic http://qa.debian.org/popcon.php?package=synaptic 7620 图形软件包管理器(APT 的 GNOME 前端)
apt-utils http://qa.debian.org/popcon.php?package=apt-utils 1275 APT 实用程序:apt-extracttemplates(1)apt-ftparchive(1)apt-sortpkgs(1)
apt-listchanges http://qa.debian.org/popcon.php?package=apt-listchanges 202 软件包更改历史记录通知工具
apt-listbugs http://qa.debian.org/popcon.php?package=apt-listbugs 370 在每次 APT 安装前列出严重错误
apt-file http://qa.debian.org/popcon.php?package=apt-file 120 APT 软件包搜索实用程序 — 命令行界面
apt-rdepends http://qa.debian.org/popcon.php?package=apt-rdepends 80 递归列出软件包依赖项

2.1. Debian 软件包管理先决条件

2.1.1. 软件包配置

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

  • 系统管理员的手动配置受到尊重。换句话说,软件包配置系统不会为了方便而进行侵入式配置。

  • 每个软件包都带有自己的配置脚本,该脚本具有名为 debconf(7) 的标准化用户界面,以帮助软件包的初始安装过程。

  • Debian 开发人员尽力通过软件包配置脚本使您的升级体验完美无瑕。

  • 打包软件的全部功能可供系统管理员使用。但是,具有安全风险的功能在默认安装中被禁用。

  • 如果您手动激活具有某些安全风险的服务,则您有责任承担风险控制。

  • 系统管理员可以手动启用深奥的配置。这可能会干扰系统配置的常用通用辅助程序。

2.1.2. 基本预防措施

[Warning] 警告

不要从随机混合的套件中安装软件包。这可能会破坏软件包的一致性,这需要深入的系统管理知识,例如编译器 ABI 版本、解释器功能等。

新手 Debian 系统管理员应坚持使用 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 套件作为其 自我管理的桌面环境 的主要系统运行。这是因为它们运行良好,更新频繁,并提供最新的功能。

[Caution] 注意

对于您的 生产服务器,建议使用带有安全更新的 stable 套件。对于您可以花费有限管理精力(例如,为您母亲的 PC)的台式 PC 也是如此。

只需在 “/etc/apt/sources.list” 中将发行版字符串设置为套件名称:“testing” 或 “unstable”;或代号:“wheezy” 或 “sid” 即可。这使您过上永久升级的生活

使用 testingunstable 非常有趣,但也存在一些风险。即使 Debian 系统的 unstable 套件在大多数情况下看起来非常稳定,但 Debian 系统的 testingunstable 套件也出现了一些软件包问题,其中一些问题并非易事。这可能对您来说相当痛苦。有时,您可能会在几周内遇到损坏的软件包或缺少功能。

以下是一些确保从 Debian 软件包中的错误中快速轻松恢复的想法。

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

  • 使安装 CD 方便用于救援启动

  • 考虑安装 apt-listbugs 以在升级前检查 Debian 错误跟踪系统 (BTS) 信息

  • 充分了解软件包系统基础架构,以便解决问题

  • 创建一个 chroot 或类似的环境,并提前在其中运行最新的系统(请参阅 第 9.8 节,“虚拟化系统”

(如果您无法执行任何一项预防措施,则您可能尚未准备好使用 testingunstable 套件。)

以下 觉悟 将人从永恒的升级 业力 斗争 地狱 中拯救出来,让他到达 Debian 涅槃

2.1.4. Debian 归档库基础知识

让我们从系统用户的角度来了解 Debian 归档库

[Tip] 提示

Debian 归档库的官方策略在 Debian 策略手册,第 2 章 - Debian 归档库 中定义。

对于典型的 HTTP 访问,归档库在 “/etc/apt/sources.list” 文件中指定如下,例如,对于当前的 stable = squeeze 系统。

deb http://ftp.XX.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.XX.debian.org/debian/ squeeze main contrib non-free

deb http://security.debian.org/ squeeze/updates main contrib
deb-src http://security.debian.org/ squeeze/updates main contrib

请注意,“ftp.XX.debian.org” 必须替换为您所在位置的相应镜像站点 URL,对于美国,为 “ftp.us.debian.org”,可以在 Debian 全球镜像站点列表 中找到。这些服务器的状态可以在 Debian 镜像检查器站点 中查看。

在这里,我倾向于使用代号 “squeeze” 而不是套件名称 “stable”,以避免在下一个 stable 发布时出现意外。

/etc/apt/sources.list” 的含义在 sources.list(5) 中描述,要点如下。

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

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

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

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

  • 第三个及后续参数是 Debian 归档库的有效归档区域名称列表。

如果仅用于不访问源代码相关元数据的 aptitude,则可以安全地省略(或通过在行首放置 “#” 注释掉)“deb-src” 行。它可以加快归档库元数据的更新速度。URL 可以是 “http://”、“ftp://”、“file://”、……。

[Tip] 提示

如果在上面的示例中使用 “sid” 而不是 “squeeze”,则 “/etc/apt/sources.list” 中用于安全更新的 “deb: http://security.debian.org/” 行不是必需的。这是因为 “sid”(unstable)没有安全更新归档库。

以下是 Debian 归档库站点的 URL 列表以及配置文件中使用的套件名称或代号。

表 2.2. Debian 归档库站点列表

归档库 URL 套件名称(代号) 用途
http://ftp.XX.debian.org/debian/ stable (squeeze) stable (squeeze) 发行版
http://ftp.XX.debian.org/debian/ testing (wheezy) testing (wheezy) 发行版
http://ftp.XX.debian.org/debian/ unstable (sid) unstable (sid) 发行版
http://ftp.XX.debian.org/debian/ experimental experimental 预发行版(可选,仅供开发人员使用)
http://ftp.XX.debian.org/debian/ stable-proposed-updates 下一个 stable 点版本的更新(可选)
http://security.debian.org/ stable/updates stable 发行版的安全更新(重要)
http://security.debian.org/ testing/updates testing 发行版的安全更新(重要)
http://ftp.XX.debian.org/debian/ squeeze-updates squeeze 的兼容更新,用于垃圾邮件过滤器、IM 客户端等
http://backports.debian.org/debian-backports/ squeeze-backports squeeze 的较新反向移植软件包(可选)

[Caution] 注意

只有纯 stable 发行版及其安全更新才能提供最佳稳定性。主要运行 stable 发行版并混合使用来自 testingunstable 发行版的一些软件包,比运行纯 unstable 发行版更具风险,因为存在库版本不匹配等问题。如果您确实需要在 stable 发行版下使用某些程序的最新版本,请使用来自 squeeze-updateshttp://backports.debian.org(请参阅 第 2.7.4 节,“更新和 Backports”)服务的软件包。必须格外小心地使用这些服务。

[Caution] 注意

您基本上应该在 “deb” 行中仅列出 stabletestingunstable 套件之一。如果您在 “deb” 行中列出 stabletestingunstable 套件的任何组合,则 APT 程序会变慢,而只有最新的归档库有效。当 “/etc/apt/preferences” 文件与明确目标一起使用时,多次列出才有意义(请参阅 第 2.7.3 节,“调整候选版本”)。

[Tip] 提示

对于具有 stabletesting 套件的 Debian 系统,最好在 “/etc/apt/sources.list” 中包含带有 “http://security.debian.org/” 的行,以启用安全更新,如上面的示例所示。

[Note] 注意

Debian 安全团队修复了 stable 归档库的安全错误。这项活动一直非常严格和可靠。testing 归档库的安全错误可能由 Debian testing 安全团队修复。由于 一些 原因,这项活动不如 stable 那样严格,您可能需要等待已修复的 unstable 软件包的迁移。unstable 归档库的安全错误由各个维护者修复。通过利用最新的上游安全修复程序,积极维护的 unstable 软件包通常处于相当良好的状态。有关 Debian 如何处理安全错误的信息,请参阅 Debian 安全 FAQ

表 2.3. Debian 归档库区域列表

区域 软件包数量 软件包组件的标准
main 36909 符合 DFSG 且不依赖于 non-free
contrib 231 符合 DFSG 但依赖于 non-free
non-free 477 不符合 DFSG

这里的软件包数量是针对 amd64 架构的。严格来说,只有 main 区域归档库应被视为 Debian 系统。

可以通过将浏览器指向每个归档库 URL 并附加 distspool 来最好地研究 Debian 归档库组织。

发行版有两种表示方式:套件或 代号。在许多文档中,发行版一词也用作套件的同义词。套件和代号之间的关系可以概括如下。

表 2.4. 套件和代号之间的关系

时间 套件 = stable 套件 = testing 套件 = unstable
squeeze 发布之后 代号 = squeeze 代号 = wheezy 代号 = sid
wheezy 发布之后 代号 = wheezy 代号 = wheezy+1 代号 = sid

代号的历史记录在 Debian FAQ:6.3.1 过去使用过哪些其他代号? 中描述。

在更严格的 Debian 归档库术语中,“section” 一词专门用于按应用程序领域对软件包进行分类。(虽然,“main section” 一词有时可能用于描述名为 “main” 的 Debian 归档库区域。)

每次 Debian 开发人员 (DD) 将新上传内容上传到 unstable 归档库(通过 incoming 处理)时,都要求 DD 确保上传的软件包与最新的 unstable 归档库中的软件包集兼容。

如果 DD 为了重要的库升级等有意破坏此兼容性,通常会向 debian-devel 邮件列表 等发布公告。

在 Debian 归档库维护脚本将一组软件包从 unstable 归档库移动到 testing 归档库之前,归档库维护脚本不仅会检查软件包的成熟度(大约 10 天),以及 RC 错误报告的状态,还会尝试确保它们与 testing 归档库中的最新软件包集兼容。此过程使 testing 归档库非常新且可用。

通过发布团队领导的渐进式归档库冻结过程,testing 归档库变得成熟,使其完全一致且没有错误,并进行了一些手动干预。然后,通过将旧 testing 归档库的代号分配给新的 stable 归档库,并为新的 testing 归档库创建新的代号来创建新的 stable 发行版。新的 testing 归档库的初始内容与新发布的 stable 归档库的内容完全相同。

unstabletesting 归档库都可能因多种因素而遭受临时故障。

  • 损坏的软件包上传到归档库(主要针对 unstable

  • 延迟接受新软件包到归档库(主要针对 unstable

  • 归档库同步时序问题(针对 testingunstable

  • 对归档库的手动干预,例如软件包删除(更多针对 testing)等。

因此,如果您决定使用这些归档库,您应该能够修复或解决这些类型的故障。

[Caution] 注意

在新 stable 发行版发布后的几个月内,即使大多数桌面用户通常使用 unstabletesting 归档库,也应使用 stable 归档库及其安全更新。在此过渡期间,unstabletesting 归档库对大多数人来说都不是很好。由于 unstable 归档库会遭受核心软件包的大量升级,因此您的系统很难保持良好的工作状态。testing 归档库也没有用,因为它包含的内容与 stable 归档库的内容大致相同,但没有其安全支持(Debian testing-security-announce 2008-12)。大约一个月后,如果您小心谨慎,unstable 归档库可能会可用。

[Tip] 提示

在跟踪 testing 归档库时,由删除的软件包引起的问题通常可以通过安装来自 unstable 归档库的相应软件包来解决,该软件包已上传用于错误修复。

有关归档库定义,请参阅 Debian 策略手册

2.1.5. 软件包依赖关系

Debian 系统通过其控制文件字段中版本化的二进制依赖关系声明机制提供了一致的二进制软件包集。以下是它们的简化定义。

  • “Depends”(依赖)

    • 这声明了一个绝对依赖关系,并且必须同时或提前安装此字段中列出的所有软件包。

  • “Pre-Depends”(预依赖)

    • 这类似于 Depends,不同之处在于它要求提前完成列表中软件包的安装。

  • “Recommends”(推荐)

    • 这声明了一个强依赖关系,但不是绝对依赖关系。大多数用户不希望安装该软件包,除非安装了此字段中列出的所有软件包。

  • “Suggests”(建议)

    • 这声明了一个弱依赖关系。此软件包的许多用户可能会从安装此字段中列出的软件包中受益,但没有它们也可以具有合理的功能。

  • “Enhances”(增强)

    • 这声明了一个类似于 Suggests 的弱依赖关系,但方向相反。

  • “Breaks”(破坏)

    • 这声明了软件包不兼容性,通常带有某些版本规范。通常,解决方案是升级此字段中列出的所有软件包。

  • “Conflicts”(冲突)

    • 这声明了一个绝对不兼容性。必须删除此字段中列出的所有软件包才能安装此软件包。

  • “Replaces”(替换)

    • 当此软件包安装的文件替换了列表中软件包中的文件时,将声明此项。

  • “Provides”(提供)

    • 当此软件包提供列表中软件包中的所有文件和功能时,将声明此项。

[Note] 注意

请注意,同时为虚拟软件包定义 “Provides”、“Conflicts” 和 “Replaces” 是合理的配置。这确保了在任何时候只能安装一个提供此虚拟软件包的真实软件包。

包括源代码依赖关系在内的官方定义可以在 策略手册:第 7 章 - 声明软件包之间的关系 中找到。

2.1.6. 软件包管理事件流

以下是 APT 软件包管理简化事件流的摘要。

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

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

    2. 重建并更新本地元数据以供 APT 使用

  • 升级(“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 脚本

  • 安装(“aptitude install …” 或 “apt-get install …”)

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

    2. 进行软件包依赖关系解析

    3. 从远程归档库获取选定的二进制软件包

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

    5. 运行 preinst 脚本

    6. 安装二进制文件

    7. 运行 postinst 脚本

  • 删除(“aptitude remove …” 或 “apt-get remove …”)

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

    2. 进行软件包依赖关系解析

    3. 运行 prerm 脚本

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

    5. 运行 postrm 脚本

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

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

    2. 进行软件包依赖关系解析

    3. 运行 prerm 脚本

    4. 删除已安装的文件,包括配置文件

    5. 运行 postrm 脚本

在这里,为了宏观概览,我故意跳过了技术细节。

2.1.7. 软件包管理故障的初步响应

您应该阅读详细的官方文档。首先要阅读的是 Debian 特有的 “/usr/share/doc/<package_name>/README.Debian” 文件。也应该参考 “/usr/share/doc/<package_name>/” 中的其他文档。如果您将 shell 设置为 第 1.4.2 节,“自定义 bash”,请键入以下内容。

$ cd <package_name>
$ pager README.Debian
$ mc

您可能需要安装带有 “-doc” 后缀的相应文档软件包以获取详细信息。

如果您在使用特定软件包时遇到问题,请务必首先查看 Debian 错误跟踪系统 (BTS) 站点。

表 2.5. 解决特定软件包问题的关键网站列表

网站 命令
Debian 错误跟踪系统 (BTS) 的主页 sensible-browser "http://bugs.debian.org/"
已知软件包名称的错误报告 sensible-browser "http://bugs.debian.org/<package_name>"
已知错误编号的错误报告 sensible-browser "http://bugs.debian.org/<bug_number>"

使用包含 “site:debian.org”、“site:wiki.debian.org”、“site:lists.debian.org” 等搜索词在 Google 上搜索。

当您提交错误报告时,请使用 reportbug(1) 命令。

2.2. 基本软件包管理操作

Debian 系统上的基本软件包管理操作可以通过 Debian 系统上可用的任何软件包管理工具来执行。在这里,我们解释基本软件包管理工具:apt-get / apt-cacheaptitude

对于涉及软件包安装或更新软件包元数据的软件包管理操作,您需要具有 root 权限。

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

apt-getapt-cache 命令是最基本的软件包管理工具。

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

  • apt-get 最适合版本之间的主要系统升级等。

  • apt-get 提供了一个强大且稳定的软件包解析器,它使用通用的软件包状态数据。

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

  • apt-get 已更新以支持推荐软件包的自动安装和自动删除。

  • apt-get 已更新以支持软件包活动的日志记录。

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

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

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

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

  • aptitude 也提供命令行用户界面。

  • aptitude 最适合日常交互式软件包管理,例如检查已安装的软件包和搜索可用的软件包。

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

  • aptitude 提供了一个增强的软件包解析器,该解析器还使用 aptitude 专用的额外软件包状态数据。

  • aptitude 支持推荐软件包的自动安装和自动删除。

  • aptitude 支持软件包活动的日志记录。

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

  • aptitude 无需使用 /etc/apt/preferences 即可管理软件包的多个版本,并且非常直观。

[Note] 注意

尽管 aptitude 命令具有丰富的功能,例如其增强的软件包解析器,但这种复杂性已导致(或可能仍然导致)一些回归,例如 Bug #411123Bug #514930Bug #570377。如有疑问,请优先使用 apt-getapt-cache 命令,而不是 aptitude 命令。

2.2.2. 使用命令行进行基本软件包管理操作

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

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

aptitude 语法 apt-get/apt-cache 语法 描述
aptitude update apt-get update 更新软件包归档元数据
aptitude install foo apt-get install foo 安装 “foo” 软件包的候选版本及其依赖项
aptitude safe-upgrade apt-get upgrade 安装已安装软件包的候选版本,而不删除任何其他软件包
aptitude full-upgrade apt-get dist-upgrade <package> 安装已安装软件包的候选版本,并在需要时删除其他软件包
aptitude remove foo apt-get remove foo 删除 “foo” 软件包,同时保留其配置文件
N/A apt-get autoremove 删除不再需要的自动安装的软件包
aptitude purge foo apt-get purge foo 彻底清除 “foo” 软件包及其配置文件
aptitude clean apt-get clean 完全清除检索到的软件包文件的本地存储库
aptitude autoclean apt-get autoclean 清除本地存储库中过时软件包的检索到的软件包文件
aptitude show foo apt-cache show <package> 显示有关 “foo” 软件包的详细信息
aptitude search <regex> apt-cache search <regex> 搜索与 <regex> 匹配的软件包
aptitude why <regex> N/A 解释应该安装与 <regex> 匹配的软件包的原因
aptitude why-not <regex> N/A 解释无法安装与 <regex> 匹配的软件包的原因

[Note] 注意

由于 apt-getaptitude 共享自动安装的软件包状态(请参阅 第 2.5.5 节,“APT 的软件包状态”),因此在 lenny 之后,您可以混合使用这些工具而不会出现重大问题(请参阅 Bug #594490)。

safe-upgrade”/“upgrade” 和 “full-upgrade”/“dist-upgrade” 之间的区别仅在新版本的软件包与其旧版本的软件包的依赖关系不同时出现。“aptitude safe-upgrade” 命令既不安装新软件包也不删除已安装的软件包。

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

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

您可以在 “aptitude” 之后直接提供命令选项。

表 2.7. aptitude(8) 的值得注意的命令选项

命令选项 描述
-s 模拟命令的结果
-d 仅下载但不安装/升级
-D 在自动安装和删除之前显示简要说明

有关更多信息,请参阅 aptitude(8) 和 “aptitude 用户手册”,路径为 “/usr/share/doc/aptitude/README”。

[Tip] 提示

dselect 软件包仍然可用,并且是以前版本中首选的全屏交互式软件包管理工具。

2.2.3. aptitude 的交互式使用

对于交互式软件包管理,您可以从控制台 shell 提示符下以交互模式启动 aptitude,如下所示。

$ sudo aptitude -u
Password:

这将更新归档信息的本地副本,并在带有菜单的全屏中显示软件包列表。Aptitude 将其配置放置在 “~/.aptitude/config”。

[Tip] 提示

如果您想使用 root 的配置而不是用户的配置,请在上面的表达式中使用 “sudo -H aptitude …” 而不是 “sudo aptitude …”。

[Tip] 提示

Aptitude 在交互式启动时会自动设置待处理的操作。如果您不喜欢这样,可以从菜单中重置它:“操作” → “取消待处理的操作”。

2.2.4. aptitude 的快捷键绑定

在此全屏模式下,用于浏览软件包状态并在其上设置“计划操作”的值得注意的按键如下。

表 2.8. aptitude 的快捷键绑定列表

按键 快捷键绑定
F10Ctrl-t 菜单
? 显示按键的帮助(更完整的列表)
F10 → 帮助 → 用户手册 显示用户手册
u 更新软件包归档信息
+ 将软件包标记为升级安装
- 将软件包标记为删除(保留配置文件)
_ 将软件包标记为清除(删除配置文件)
= 将软件包置于保持状态
U 标记所有可升级的软件包(功能类似于 full-upgrade
g 开始下载安装选定的软件包
q 退出当前屏幕并保存更改
x 退出当前屏幕并放弃更改
Enter 查看有关软件包的信息
C 查看软件包的更改日志
l 更改显示的软件包的限制
/ /
\ 搜索第一个匹配项

n

[Tip] 提示

重复上次搜索

命令行和按下 “l” 和 “//” 后的菜单提示的文件名规范采用如下所述的 aptitude 正则表达式。Aptitude 正则表达式可以使用以 “~n” 开头并后跟软件包名称的字符串显式匹配软件包名称。

您需要按 “U” 以将所有已安装的软件包升级到可视化界面中的候选版本。否则,只有选定的软件包和某些具有版本依赖关系的软件包才会升级到候选版本

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

2.2.5. aptitude 下的软件包视图

  • aptitude(8) 的交互式全屏模式下,软件包列表中的软件包显示如下例所示。

  • 在这里,此行从左到右的含义如下。

  • “当前状态”标志(第一个字母)

  • “计划操作”标志(第二个字母)

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

  • 软件包名称

  • 归因于“计划操作”的磁盘空间使用量变化

[Tip] 提示

软件包的当前版本

软件包的候选版本

完整的标志列表在按 “?” 显示的帮助屏幕底部给出。

候选版本是根据当前的本地首选项选择的(请参阅 apt_preferences(5)第 2.7.3 节,“调整候选版本”)。

菜单 “视图” 下提供了几种类型的软件包视图。 表 2.9. aptitude 的视图列表 视图
状态 视图描述 软件包视图
良好 视图描述 请参阅 表 2.10,“标准软件包视图的分类”(默认)
审核建议 视图描述 列出一些已安装软件包推荐但尚未安装的软件包
平面软件包列表 不带分类的软件包列表(用于正则表达式) Debtags 浏览器
非常有用 列出根据其 debtags 条目分类的软件包 分类浏览器

[Note] 注意

已弃用

列出根据其类别分类的软件包(请改用 Debtags 浏览器

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

标准的 “软件包视图” 对软件包进行分类,有点像 dselect,但具有一些额外的功能。 视图
表 2.10. 标准软件包视图的分类 类别
可升级的软件包 , ,
将软件包组织为 sectionareapackage , ,
新软件包 , ,
已安装的软件包 , ,
未安装的软件包 过时和本地创建的软件包
虚拟软件包 列出具有相同功能的软件包

[Tip] 提示

任务

列出通常执行某项任务所需的不同功能的软件包

任务视图可用于精选您的任务所需的软件包。

  • 2.2.6. aptitude 的搜索方法选项

    • Aptitude 提供了几个选项,供您使用其正则表达式公式搜索软件包。

    • Shell 命令行

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

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

    • 交互式全屏模式

    • l” 将软件包视图限制为匹配的软件包

    • /” 搜索匹配的软件包

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

[Tip] 提示

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>
匹配软件包部分 ~s<regex_section>
匹配软件包版本 ~V<regex_version>}
匹配归档 ~A{sarge,etch,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
匹配具有损坏的 depends/predepends/conflict 的软件包 ~B<type>
匹配从中定义了与 <term> 软件包的关系 <type> 的软件包 ~D[<type>:]<term>
匹配从中定义了与 <term> 软件包的损坏的关系 <type> 的软件包 ~DB[<type>:]<term>
匹配 <term> 软件包定义了关系 <type> 的软件包 ~R[<type>:]<term>
匹配 <term> 软件包定义了损坏的关系 <type> 的软件包 ~RB[<type>:]<term>
匹配某些其他已安装软件包依赖的软件包 ~R~i
匹配没有其他已安装软件包依赖的软件包 !~R~i
匹配某些其他已安装软件包依赖或推荐的软件包 ~R~i|~Rrecommends:~i
匹配带有过滤版本的 <term> 软件包 ~S filter <term>
匹配所有软件包(真) ~T

  • 不匹配任何软件包(假)

  • ~F

  • 正则表达式部分与典型的类 Unix 文本工具中使用的 ERE 相同,使用 “^”、“.*”、“$” 等,如 egrep(1)awk(1)perl(1) 中所示。

[Tip] 提示

关系 <type> 是以下之一(depends、predepends、recommends、suggests、conflicts、replaces、provides)。

默认关系类型为 “depends”。

  • 当 <regex_pattern> 为空字符串时,请在命令后立即放置 “~T”。

  • 以下是一些快捷方式。

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

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

[Note] 注意

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

熟悉 mutt 的用户可以很快上手,因为 mutt 是表达式语法的灵感来源。请参阅 “用户手册” “/usr/share/doc/aptitude/README” 中的 “SEARCHING, LIMITING, AND EXPRESSIONS”。

使用 aptitude(8)lenny 版本,新的长格式语法(例如 “?broken”)可以用于正则表达式匹配,以替代其旧的短格式等效项 “~b”。现在,空格字符 “ ” 被视为正则表达式终止字符之一,此外还有波浪号字符 “~”。有关新的长格式语法,请参阅 “用户手册”。

[Note] 注意

2.2.8. aptitude 的依赖关系解析

aptitude 中选择软件包不仅会拉取在其 “Depends:” 列表中定义的软件包,还会拉取在 “Recommends:” 列表中定义的软件包(如果菜单 “F10 → 选项 → 依赖关系处理” 设置为相应的值)。如果 aptitude 下不再需要这些自动安装的软件包,它们将被自动删除。

lenny 版本之前,apt-get 和其他标准 APT 工具不提供自动删除功能。

2.2.9. 软件包活动日志

您可以检查日志文件中的软件包活动历史记录。 表 2.12. 软件包活动的日志文件
文件 内容
/var/log/dpkg.log 所有软件包活动的 dpkg 级别活动日志
/var/log/apt/term.log 通用 APT 活动日志

/var/log/aptitude

aptitude 命令活动日志

实际上,从这些日志中快速获得有意义的理解并不容易。有关更简单的方法,请参阅 第 9.2.10 节,“记录配置文件中的更改”

2.3. aptitude 操作示例

以下是一些 aptitude(8) 操作的示例。

$ aptitude search '~n(pam|nss).*ldap'
p libnss-ldap - NSS module for using LDAP as a naming service
p libpam-ldap - Pluggable Authentication Module allowing LDAP interfaces

2.3.1. 列出与软件包名称的正则表达式匹配的软件包

以下命令列出与软件包名称的正则表达式匹配的软件包。

这对于您查找软件包的确切名称非常方便。

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

“新平面软件包列表” 视图中带有 “l” 提示的正则表达式 “~dipv6” 将视图限制为具有匹配描述的软件包,并允许您以交互方式浏览其信息。

2.3.3. 彻底清除已删除的软件包

# aptitude search '~c'

您可以清除已删除软件包的所有剩余配置文件。

# aptitude purge '~c'

检查以下命令的结果。

如果您认为列出的软件包可以清除,请执行以下命令。

您可能希望在交互模式下执行类似操作以进行细粒度控制。

您在 “新平面软件包列表” 视图中提供正则表达式 “~c” 和 “l” 提示。这会将软件包视图限制为仅与正则表达式匹配的软件包,即 “已删除但未清除”。可以通过在顶级标题处按 “[” 来显示所有这些与正则表达式匹配的软件包。

然后,您在顶级标题(例如 “已安装的软件包”)处按 “_”。只有标题下与正则表达式匹配的软件包才会被标记为清除。您可以通过交互式地为每个软件包按 “=” 来排除要清除的某些软件包。

此技术非常方便,并且适用于许多其他命令键。

  1. 2.3.4. 整理自动/手动安装状态

  2. 以下是我如何整理软件包的自动/手动安装状态(在使用非 aptitude 软件包安装程序等之后)。

  3. 以 root 身份在交互模式下启动 aptitude

  4. 键入 “u”、“U”、“f” 和 “g” 以更新和升级软件包列表和软件包。

  5. 键入 “l” 以输入软件包显示限制为 “~i(~R~i|~Rrecommends:~i)”,并在 “已安装的软件包” 上键入 “M” 作为自动安装。

  6. 键入 “l” 以输入软件包显示限制为 “~prequired|~pimportant|~pstandard|~E”,并在 “已安装的软件包” 上键入 “m” 作为手动安装。

  7. 键入 “l” 以输入软件包显示限制为 “~i!~M”,并通过在 “已安装的软件包” 上键入 “[” 来公开未使用的软件包后,通过在每个软件包上键入 “-” 来删除它们。

  8. 键入 “l” 以输入软件包显示限制为 “~i”,并在 “任务” 上键入 “m” 作为手动安装。

  9. 退出 aptitude

  10. 以 root 身份启动 “apt-get -s autoremove|less” 以检查哪些未使用。

  11. 以交互模式重启 aptitude,并将需要的软件包标记为 “m”。

以 root 身份重启 “apt-get -s autoremove|less” 以重新检查 REMOVED 是否仅包含预期的软件包。

以 root 身份启动 “apt-get autoremove|less” 以自动删除未使用的软件包。

[Note] 注意

任务” 上的 “m” 操作是可选的,以防止将来出现大规模软件包删除的情况。

2.3.5. 系统范围的升级

当迁移到新版本等时,即使 Debian 可以像下面描述的那样升级,您也应该考虑执行新系统的全新安装。这为您提供了清除收集的垃圾的机会,并使您有机会接触到最新软件包的最佳组合。当然,在执行此操作之前,您应该将系统的完整备份到安全位置(请参阅 第 10.1.6 节,“备份和恢复”)。我建议使用不同的分区进行双启动配置,以实现最平滑的过渡。

您可以通过更改指向新版本的 “/etc/apt/sources.list” 文件的内容并运行 “apt-get update; apt-get dist-upgrade” 命令来执行系统范围的升级到较新版本。

要从 stable 升级到 testingunstable,您需要将 第 2.1.4 节,“Debian 归档基础知识” 的 “/etc/apt/sources.list” 示例中的 “squeeze” 替换为 “wheezy” 或 “sid”。

实际上,由于某些软件包转换问题(主要是由于软件包依赖关系),您可能会遇到一些复杂情况。升级的差异越大,您遇到麻烦的可能性就越大。对于从旧 stable 到新 stable 的过渡(在其发布之后),您可以阅读其新的 发行说明,并遵循其中描述的确切过程,以最大程度地减少麻烦。

  1. 当您决定在 testing 正式发布之前从 stable 迁移到 testing 时,没有 发行说明 可以帮助您。在前一个 stable 版本发布后,stabletesting 之间的差异可能会变得非常大,这使得升级情况变得复杂。

  2. 您应该在从邮件列表收集最新信息并使用常识的同时,为全面升级采取预防措施。

  3. 阅读以前的 “发行说明”。

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

  5. 手头准备好可启动介质,以应对引导加载程序损坏的情况。

  6. 提前充分告知系统上的用户。

  7. 使用 script(1) 记录升级活动。

  8. 将 “unmarkauto” 应用于所需的软件包,例如 “aptitude unmarkauto vim”,以防止删除。

  9. 最小化已安装的软件包以减少软件包冲突的机会,例如,删除桌面任务软件包。

  10. 删除 “/etc/apt/preferences” 文件(禁用 apt-pinning)。

  11. 尝试逐步升级:oldstablestabletestingunstable

  12. 更新 “/etc/apt/sources.list” 文件以仅指向新归档,并运行 “aptitude update”。

  13. (可选)首先安装新的核心软件包,例如 “aptitude install perl”。

[Caution] 注意

运行 “apt-get -s dist-upgrade” 命令以评估影响。

[Caution] 注意

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

stable 版本之间升级时,跳过主要的 Debian 版本是不明智的。

在以前的 “发行说明” 中,GCC、Linux Kernel、initrd-tools、Glibc、Perl、APT 工具链等在系统范围的升级中需要一些特别注意。

有关 unstable 中的每日升级,请参阅 第 2.4.3 节,“软件包问题保障”

2.4. 高级软件包管理操作

2.4.1. 使用命令行进行高级软件包管理操作

命令 以下是其他软件包管理操作的列表,对于这些操作,aptitude 太过高级或缺少所需的功能。
表 2.13. 高级软件包管理操作列表 操作
COLUMNS=120 dpkg -l <package_name_pattern> 列出已安装软件包的状态以用于错误报告
dpkg -L <package_name> 列出已安装软件包的内容
dpkg -L <package_name> | egrep '/usr/share/man/man.*/.+' 列出已安装软件包的 manpages
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 审核系统以查找部分安装的软件包
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>-<debian_version>.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>-<debian_version><arch>.deb 将本地软件包安装到系统
debi <package_name><version>-<debian_version><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 <package_name>”)

[Caution] 注意

诸如“dpkg -i …”和“debi …”等较低级别的软件包工具应由系统管理员谨慎使用。它们不会自动处理所需的软件包依赖关系。Dpkg 的命令行选项“--force-all”以及类似的选项(参见 dpkg(1))仅供专家使用。在没有完全理解其效果的情况下使用它们可能会破坏你的整个系统。

请注意以下事项。

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

  • 与使用正则表达式的 aptitude(参见 第 1.6.2 节,“正则表达式”)不同,其他软件包管理命令使用类似于 shell glob 的模式(参见 第 1.5.6 节,“Shell glob”)。

  • apt-file 软件包提供的 apt-file(1) 必须预先运行 “apt-file update”。

  • configure-debian 软件包提供的 configure-debian(8) 运行 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 软件包。

  • 使用 “apt-get source” 的(重新)打包过程请参见 第 2.7.13 节,“将软件包移植到稳定系统”

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

  • 有关通用打包,请参见 第 12.11 节,“制作 Debian 软件包”

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

debsums 的安装启用使用 debsums(1) 针对 “/var/lib/dpkg/info/*.md5sums” 文件中的 MD5sum 值验证已安装的软件包文件。有关 MD5sum 如何工作,请参见 第 10.4.5 节,“MD5 校验和”

[Note] 注意

由于 MD5sum 数据库可能被入侵者篡改,debsums(1) 作为安全工具的用途有限。它仅适用于检查管理员的本地修改或由于介质错误造成的损坏。

2.4.3. 软件包问题保障

许多用户喜欢关注 Debian 系统的 unstable 发行版,以获取其新功能和软件包。这使得系统更容易受到严重软件包错误的影响。

安装 apt-listbugs 软件包可以通过在使用 APT 系统升级时自动检查 Debian BTS 中的严重错误来保护你的系统免受严重错误的影响。

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

2.4.4. 搜索软件包元数据

尽管访问 Debian 站点 http://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://ftp.us.debian.org/debian/”。其归档结构可以通过 Web 浏览器浏览。有 6 种关键元数据类型。

表 2.14. Debian 归档元数据的内容

您可以检查日志文件中的软件包活动历史记录。 位置 表 2.12. 软件包活动的日志文件
Release 发行版顶部 归档描述和完整性信息
Release.gpg 发行版顶部 使用归档密钥签名的 “Release” 文件的签名文件
Contents-<architecture> 发行版顶部 相关归档中所有软件包的所有文件列表
Release 每个发行版/区域/架构组合的顶部 用于 apt_preferences(5) 规则的归档描述
Packages 每个发行版/区域/二进制架构组合的顶部 二进制软件包的串联 debian/control
Sources 每个发行版/区域/源代码组合的顶部 源代码包的串联 debian/control

在最近的归档中,这些元数据存储为压缩文件和差异文件,以减少网络流量。

2.5.2. 顶级 “Release” 文件和真实性

[Tip] 提示

顶级 “Release” 文件用于在 安全 APT 系统下签名归档。

Debian 归档的每个套件都有一个顶级 “Release” 文件,例如 “http://ftp.us.debian.org/debian/dists/unstable/Release”,如下所示。

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

在这里,你可以找到我在 第 2.1.4 节,“Debian 归档基础知识” 中使用 “suite” 和 “codeneme” 的理由。“distribution” 用于指代 “suite” 和 “codeneme” 两者。归档提供的所有归档 “area” 名称都列在 “Component” 下。

顶级 “Release” 文件的完整性通过称为 secure apt 的加密基础设施进行验证。

  • 加密签名文件 “Release.gpg” 是从真实的顶级 “Release” 文件和秘密 Debian 归档密钥创建的。

  • 公共 Debian 归档密钥可以植入 “/etc/apt/trusted.gpg” 中;

  • 安全 APT 系统通过 “Release.gpg” 文件和 “/etc/apt/trusted.gpg” 中的公共 Debian 归档密钥,以加密方式验证下载的顶级 “Release” 文件的完整性。

所有 “Packages” 和 “Sources” 文件的完整性通过使用其顶级 “Release” 文件中的 MD5sum 值进行验证。所有软件包文件的完整性通过使用 “Packages” 和 “Sources” 文件中的 MD5sum 值进行验证。参见 debsums(1)第 2.4.2 节,“已安装软件包文件的验证”

由于加密签名验证比 MD5sum 值计算的 CPU 密集程度更高,因此在使用顶级 “Release” 文件的加密签名的同时,为每个软件包使用 MD5sum 值可以提供 良好的安全性和性能(参见 第 10.4 节,“数据安全基础设施”)。

2.5.3. 归档级别 “Release” 文件

[Tip] 提示

归档级别 “Release” 文件用于 apt_preferences(5) 的规则。

对于 “/etc/apt/sources.list” 中 “deb” 行指定的所有归档位置,都有归档级别 “Release” 文件,例如 “http://ftp.us.debian.org/debian/dists/unstable/main/binary-amd64/Release” 或 “http://ftp.us.debian.org/debian/dists/sid/main/binary-amd64/Release”,如下所示。

Archive: unstable
Origin: Debian
Label: Debian
Component: main
Architecture: amd64
[Caution] 注意

对于 “Archive:” 节,套件名称(“stable”、“testing”、“unstable”,…)在 Debian 归档 中使用,而代号(“dapper”、“feisty”、“gutsy”、“hardy”、“intrepid”,…)在 Ubuntu 归档 中使用。

对于某些归档,例如 experimentalsqueeze-backports,其中包含不应自动安装的软件包,还有额外的行,例如 “http://ftp.us.debian.org/debian/dists/experimental/main/binary-amd64/Release”,如下所示。

Archive: experimental
Origin: Debian
Label: Debian
NotAutomatic: yes
Component: main
Architecture: amd64

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

2.5.4. 获取软件包的元数据

当使用 APT 工具(例如 aptitudeapt-getsynapticapt-fileauto-apt…)时,我们需要更新包含 Debian 归档信息的元数据的本地副本。这些本地副本具有以下文件名,对应于 “/etc/apt/sources.list” 中指定的 distributionareaarchitecture 名称(参见 第 2.1.4 节,“Debian 归档基础知识”)。

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

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

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

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

  • /var/cache/apt/apt-file/ftp.us.debian.org_debian_dists_<distribution>_Contents-<architecture>.gz”(对于 apt-file

前 4 种类型的文件由所有相关的 APT 命令共享,并通过命令行 “apt-get update” 和 “aptitude update” 更新。如果 “/etc/apt/sources.list” 中有 “deb” 行,则会更新 “Packages” 元数据。如果 “/etc/apt/sources.list” 中有 “deb-src” 行,则会更新 “Sources” 元数据。

Packages” 和 “Sources” 元数据包含指向二进制和源代码软件包文件位置的 “Filename:” 节。目前,这些软件包位于 “pool/” 目录树下,以便在发行版之间进行改进的过渡。

Packages” 元数据的本地副本可以通过 aptitude 以交互方式搜索。专用搜索命令 grep-dctrl(1) 可以搜索 “Packages” 和 “Sources” 元数据的本地副本。

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” 中存储其本地生成的安装状态信息,该信息仅供其使用。

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

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

2.5.8. Debian 软件包文件名

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

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

软件包类型 名称结构
二进制软件包(又名 deb <package-name>_<epoch>:<upstream-version>-<debian.version>-<architecture>.deb
二进制软件包(又名 udeb <package-name>_<epoch>:<upstream-version>-<debian.version>-<architecture>.udeb
源代码包(上游源代码) <package-name>_<epoch>:<upstream-version>-<debian.version>.orig.tar.gz
1.0 源代码包(Debian 更改) <package-name>_<epoch>:<upstream-version>-<debian.version>.diff.gz
3.0 (quilt) 源代码包(Debian 更改) <package-name>_<epoch>:<upstream-version>-<debian.version>.debian.tar.gz
源代码包(描述) <package-name>_<epoch>:<upstream-version>-<debian.version>.dsc

[Tip] 提示

这里仅描述了基本的源代码包格式。有关更多信息,请参见 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,.,,~] 可选

[Note] 注意

你可以通过 dpkg(1) 检查软件包版本顺序,例如 “dpkg --compare-versions 7.0 gt 7.~pre1 ; echo $?”。

[Note] 注意

debian-installer (d-i) 使用 udeb 作为其二进制软件包的文件扩展名,而不是普通的 debudeb 软件包是精简版的 deb 软件包,它删除了一些非必要的内容(例如文档)以节省空间,同时放宽了软件包策略要求。debudeb 软件包都共享相同的软件包结构。“u” 代表 micro。

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 章,I18N 和 L10N)支持。

表 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/diversions dpkg(1) 使用并由 `dpkg-divert`(8) 设置的转移信息
/var/lib/dpkg/statoverride dpkg(1) 使用并由 `dpkg-statoverride`(8) 设置的 stat 覆盖信息
/var/lib/dpkg/status 所有软件包的状态信息
/var/lib/dpkg/status-old var/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” 元数据的本地副本。

[Tip] 提示

debian-installer 环境中,udpkg 命令用于打开 udeb 软件包。udpkg 命令是 dpkg 命令的精简版本。

2.5.10. update-alternative 命令

Debian 系统具有使用 update-alternatives(8) 和平安装一些重叠程序的机制。例如,你可以使 vi 命令选择运行 vim,同时安装 vimnvi 软件包。

$ ls -l $(type -p vi)
lrwxrwxrwx 1 root root 20 2007-03-24 19:05 /usr/bin/vi -> /etc/alternatives/vi
$ sudo update-alternatives --display vi
...
$ sudo update-alternatives --config vi
  Selection    Command
 ----------------------------------------------
      1        /usr/bin/vim
*+    2        /usr/bin/nvi

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) 命令提供的 Stat 覆盖 是一种告诉 dpkg(1) 在安装软件包时为 文件 使用不同的所有者或模式的方法。如果指定了 “--update” 并且文件存在,则会立即将其设置为新的所有者和模式。

[Caution] 注意

系统管理员使用 chmodchown 命令直接更改软件包拥有的 文件 的所有者或模式将在下次软件包升级时重置。

[Note] 注意

我在这里使用 文件 一词,但实际上这可以是 dpkg 处理的任何文件系统对象,包括目录、设备等。

2.5.12. dpkg-divert 命令

dpkg-divert(8) 命令提供的文件转移是一种强制 dpkg(1) 不要将文件安装到其默认位置,而是安装到转移位置的方法。dpkg-divert 的使用旨在用于软件包维护脚本。系统管理员随意使用它已被弃用。

2.6. 从损坏的系统恢复

当运行 unstable 系统时,管理员应能够从损坏的软件包管理情况中恢复。

[Caution] 注意

此处描述的一些方法是高风险操作。你已被警告!

2.6.1. 与旧用户配置不兼容

如果桌面 GUI 程序在重要的上游版本升级后遇到不稳定情况,你应该怀疑它与旧的本地配置文件相互干扰。如果它在新创建的用户帐户下稳定,则证实了此假设。(这是软件包的错误,通常由打包者避免。)

要恢复稳定性,你应该移动相应的本地配置文件并重新启动 GUI 程序。你可能需要读取旧配置文件内容以稍后恢复配置信息。(不要太快删除它们。)

2.6.2. 具有重叠文件的不同软件包

归档级别软件包管理系统(例如 aptitude(8)apt-get(1))甚至不会尝试使用软件包依赖项安装具有重叠文件的软件包(参见 第 2.1.5 节,“软件包依赖项”)。

软件包维护者的错误或系统管理员部署不一致的混合归档源(参见 第 2.7.2 节,“来自混合归档源的软件包”)可能会创建软件包依赖项定义不正确的情况。当你在这种情况下使用 aptitude(8)apt-get(1) 安装具有重叠文件的软件包时,解压缩软件包的 dpkg(1) 确保返回错误给调用程序,而不会覆盖现有文件。

[Caution] 注意

第三方软件包的使用通过以 root 权限运行并可以对你的系统执行任何操作的维护者脚本引入了重大的系统风险。dpkg(1) 命令仅防止解压缩时的覆盖。

你可以通过首先删除旧的冲突软件包 <old-package> 来解决此类损坏的安装。

$ 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” 来强制返回成功

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

# dpkg --configure -a

2.6.4. 使用 dpkg 命令救援

由于 dpkg 是非常低级别的软件包工具,因此它可以在非常糟糕的情况下运行,例如无法启动的系统且没有网络连接。假设 foo 软件包已损坏并且需要更换。

您可能仍然可以在软件包缓存目录中找到旧版本的 foo 软件包的缓存副本,这些旧版本没有错误: “/var/cache/apt/archives/”。 (如果找不到,您可以从 http://snapshot.debian.net/ 的存档下载,或者从正常运行的机器的软件包缓存中复制。)

如果您的系统可以启动,您可以使用以下命令安装它。

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

如果系统损坏程度较轻,您可以选择使用更高级的 APT 系统,按照 第 2.7.10 节,“紧急降级” 的说明,降级整个系统。

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

  1. 使用 debian-installer CD 以救援模式启动系统。

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

  3. 通过以下方式安装旧版本的 foo 软件包。

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

即使硬盘上的 dpkg 命令已损坏,此示例仍然有效。

[Tip] 提示

任何通过硬盘上的另一个系统、Live GNU/Linux CD、可启动 USB 密钥驱动器或网络启动启动的 GNU/Linux 系统都可以类似地用于救援损坏的系统。

如果尝试以这种方式安装软件包由于某些依赖关系冲突而失败,并且您确实需要将其作为最后的手段,则可以使用 dpkg 的 “--ignore-depends”、“--force-depends” 和其他选项来覆盖依赖关系。 如果您这样做,您需要认真努力在以后恢复正确的依赖关系。 有关详细信息,请参阅 dpkg(8)

[Note] 注意

当您的系统严重损坏时,您应该对系统进行完整备份到安全位置(请参阅 第 10.1.6 节,“备份和恢复”),并应执行全新安装。 这样更省时,最终效果更好。

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/” 中的目录中恢复一些信息,以指导您的新安装。

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

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

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

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

然后,您将看到要安装的软件包名称。 (可能有一些非软件包名称,例如 “texmf”。)

2.7. 软件包管理技巧

2.7.1. 如何选择 Debian 软件包

您可以使用 aptitude 从软件包描述或 “Tasks”(任务)下的列表中查找满足您需求的软件包。

当您遇到 2 个以上类似的软件包,并且想知道要安装哪个软件包而又不想进行 “试错” 时,您应该使用一些 常识。 我认为以下几点是首选软件包的良好指示。

  • Essential: yes > no (必要:是 > 否)

  • Component: main > contrib > non-free (组件:main > contrib > non-free)

  • Priority: required > important > standard > optional > extra (优先级:required > important > standard > optional > extra)

  • Tasks: packages listed in tasks such as "Desktop environment" (任务:任务中列出的软件包,例如 “桌面环境”)

  • Packages selected by the dependency package (e.g., python2.4 by python) (依赖软件包选择的软件包(例如,python 选择 python2.4))

  • Popcon: higher in the vote and install number (Popcon:投票数和安装数较高)

  • Changelog: regular updates by the maintainer (更新日志:维护者定期更新)

  • BTS: No RC bugs (no critical, no grave, and no serious bugs) (BTS:没有 RC 错误(没有严重、灾难性和严重错误))

  • BTS: responsive maintainer to bug reports (BTS:维护者对错误报告响应迅速)

  • BTS: higher number of the recently fixed bugs (BTS:最近修复的错误数量较多)

  • BTS: lower number of remaining non-wishlist bugs (BTS:剩余的非愿望清单错误数量较少)

Debian 是一个志愿者项目,采用分布式开发模式,其存档包含许多具有不同重点和质量的软件包。 您必须自行决定如何处理它们。

2.7.2. 来自混合存档源的软件包

[Caution] 注意

官方 Debian 发行版不支持从混合存档源安装软件包,除非官方支持特定的存档组合,例如 stable安全更新squeeze-updates

这是一个示例,说明如何在跟踪 testing 以进行单次操作时,包含在 unstable 中找到的特定较新上游版本软件包。

  1. 临时将 “/etc/apt/sources.list” 文件更改为单个 “unstable” 条目。

  2. 运行 “aptitude update”。

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

  4. 恢复 testing 的原始 “/etc/apt/sources.list” 文件。

  5. 运行 “aptitude update”。

您无需创建 “/etc/apt/preferences” 文件,也无需担心使用此手动方法进行 apt-pinning。 但这非常麻烦。

[Caution] 注意

当使用混合存档源时,您必须自行确保软件包的兼容性,因为 Debian 不保证这一点。 如果存在软件包不兼容性,您可能会破坏系统。 您必须能够判断这些技术要求。 使用随机存档的混合源是完全可选的操作,我不鼓励您使用它。

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

  • 非二进制软件包(“Architecture: all”)安装起来 更安全

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

    • 解释器程序软件包:必须提供兼容的解释器

  • 二进制软件包(非 “Architecture: all”)通常会遇到许多障碍,并且安装起来 不安全

    • 库版本兼容性(包括 “libc”)

    • 相关的实用程序版本兼容性

    • 内核 ABI 兼容性

    • C++ ABI 兼容性

[Note] 注意

为了使软件包安装起来 更安全,一些商业非自由二进制程序软件包可能会提供完全静态链接的库。 您仍然应该检查它们的 ABI 兼容性问题等。

[Note] 注意

除了避免短期内软件包损坏之外,从官方不支持的存档安装二进制软件包通常是一个坏主意。 即使您使用 apt-pinning(请参阅 第 2.7.3 节,“调整候选版本”)也是如此。 您应该考虑 chroot 或类似技术(请参阅 第 9.8 节,“虚拟化系统”)来运行来自不同存档的程序。

2.7.3. 调整候选版本

在没有 “/etc/apt/preferences” 文件的情况下,APT 系统使用版本字符串选择最新的可用版本作为 候选版本。 这是正常状态,也是 APT 系统最推荐的用法。 所有官方支持的存档组合都不需要 “/etc/apt/preferences” 文件,因为某些不应作为自动升级源的存档被标记为 NotAutomatic 并得到妥善处理。

[Tip] 提示

版本字符串比较规则可以使用例如 “dpkg --compare-versions ver1.1 gt ver1.1~1; echo $?” 来验证(请参阅 dpkg(1))。

当您定期从混合存档源安装软件包时(请参阅 第 2.7.2 节,“来自混合存档源的软件包”),您可以通过创建包含正确条目的 “/etc/apt/preferences” 文件并调整 候选版本 的软件包选择规则来自动化这些复杂的操作,如 apt_preferences(5) 中所述。 这称为 apt-pinning

[Warning] 警告

新手用户使用 apt-pinning 肯定会造成重大麻烦。 除非您绝对需要,否则必须避免使用 apt-pinning。

[Caution] 注意

当使用 apt-pinning 时,您必须自行确保软件包的兼容性,因为 Debian 不保证这一点。 apt-pinning 是完全可选的操作,我不鼓励您使用它。

[Caution] 注意

存档级别的 Release 文件(请参阅 第 2.5.3 节,“存档级别 "Release" 文件”)用于 apt_preferences(5) 的规则。 因此,apt-pinning 仅适用于 普通 Debian 存档安全 Debian 存档 的 “suite” 名称。 (这与 Ubuntu 存档不同)。 例如,您可以在 “/etc/apt/preferences” 文件中执行 “Pin: release a=unstable”,但不能执行 “Pin: release a=sid”。

[Caution] 注意

当您使用非 Debian 存档作为 apt-pinning 的一部分时,您应该检查它们的用途并检查其可信度。 例如,Ubuntu 和 Debian 不应混合使用。

[Note] 注意

即使您不创建 “/etc/apt/preferences” 文件,您也可以执行相当复杂的系统操作(请参阅 第 2.6.4 节,“使用 dpkg 命令救援”第 2.7.2 节,“来自混合存档源的软件包”),而无需 apt-pinning。

这是 apt-pinning 技术的简化说明。

APT 系统从 “/etc/apt/sources.list” 文件中定义的可用软件包源中选择最高 Pin-Priority 的 升级 软件包作为 候选版本 软件包。 如果软件包的 Pin-Priority 大于 1000,则会删除此 升级 的版本限制,以启用降级(请参阅 第 2.7.10 节,“紧急降级”)。

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

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

Pin-Priority apt-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”。

来自多个存档源的 <package> 的 apt-pinning 情况 由 “apt-cache policy <package>” 显示。

  • 以 “Package pin:” 开头的行如果仅定义了与 <package> 的关联,则列出 pin 的软件包版本,例如 “Package pin: 0.190”。

  • 如果未定义仅与 <package> 的关联,则不存在 “Package pin:” 行。

  • 仅与 <package> 关联的 Pin-Priority 值列在所有版本字符串的右侧,例如 “0.181 700”。

  • 如果未定义仅与 <package> 的关联,则在所有版本字符串的右侧列出 “0”,例如 “0.181 0”。

  • 存档的 Pin-Priority 值(在 “/etc/apt/preferences” 文件中定义为 “Package: *”)列在所有存档路径的左侧,例如 “100 http://backports.debian.org/debian-backports/ squeeze-backports/main Packages”。

2.7.4. 更新和 Backports

squeeze-updatesbackports.debian.org 存档,它们为 stable (squeeze) 提供升级软件包。

为了使用这些存档,您需要在 “/etc/apt/sources.list” 文件中列出所有必需的存档,如下所示。

deb http://ftp.us.debian.org/debian/ squeeze main contrib non-free
deb http://security.debian.org/ squeeze/updates main contrib
deb http://ftp.us.debian.org/debian/ squeeze-updates main contrib non-free
deb http://backports.debian.org/debian-backports/ squeeze-backports main contrib non-free

无需在 “/etc/apt/preferences” 文件中显式设置 Pin-Priority 值。 当有较新的软件包可用时,默认配置会提供最合理的升级(请参阅 第 2.5.3 节,“存档级别 "Release" 文件”)。

  • 所有已安装的旧软件包都将从 squeeze-updates 升级到较新的软件包。

  • 只有手动安装的来自 squeeze-backports 的旧软件包才会从 squeeze-backports 升级到较新的软件包。

每当您希望手动从 squeeze-backports 存档安装名为 “<package-name>” 的软件包及其依赖项时,您可以使用以下命令,同时使用 “-t” 选项切换目标发布版。

$ sudo apt-get install -t squeeze-backports <package-name>

2.7.5. 阻止 “Recommends”(推荐)安装的软件包

如果您不希望通过 “Recommends”(推荐)自动拉入特定软件包,则必须创建 “/etc/apt/preferences” 文件,并在其顶部显式列出所有这些软件包,如下所示。

Package: <package-1>
Pin: version *
Pin-Priority: -1

Package: <package-2>
Pin: version *
Pin-Priority: -1

2.7.6. 使用来自 unstable 的一些软件包跟踪 testing

这是一个 apt-pinning 技术的示例,用于包含在跟踪 testing 时定期升级的 unstable 中找到的特定较新上游版本软件包。 您需要在 “/etc/apt/sources.list” 文件中列出所有必需的存档,如下所示。

deb http://ftp.us.debian.org/debian/ testing main contrib non-free
deb http://ftp.us.debian.org/debian/ unstable main contrib non-free
deb http://security.debian.org/ testing/updates main contrib

将 “/etc/apt/preferences” 文件设置为如下所示。

Package: *
Pin: release a=unstable
Pin-Priority: 100

当您希望在此配置下从 unstable 存档安装名为 “<package-name>” 的软件包及其依赖项时,您需要发出以下命令,该命令使用 “-t” 选项切换目标发布版(unstable 的 Pin-Priority 变为 990。)。

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

使用此配置,通常执行 “apt-get upgrade” 和 “apt-get dist-upgrade”(或 “aptitude safe-upgrade” 和 “aptitude full-upgrade”)会升级从 testing 存档安装的软件包(使用当前的 testing 存档)以及从 unstable 存档安装的软件包(使用当前的 unstable 存档)。

[Caution] 注意

小心不要从 “/etc/apt/sources.list” 文件中删除 “testing” 条目。 如果其中没有 “testing” 条目,APT 系统将使用较新的 unstable 存档升级软件包。

[Tip] 提示

我通常在上述操作后立即编辑 “/etc/apt/sources.list” 文件,以注释掉 “unstable” 存档条目。 这避免了由于 “/etc/apt/sources.list” 文件中条目过多而导致的缓慢更新过程,尽管这会阻止使用当前的 unstable 存档升级从 unstable 存档安装的软件包。

[Tip] 提示

如果 “Pin-Priority: 1” 用于 “/etc/apt/preferences” 文件而不是 “Pin-Priority: 100”,即使删除了 “/etc/apt/sources.list” 文件中的 “testing” 条目,Pin-Priority 值为 100 的已安装软件包也不会被 unstable 存档升级。

如果您希望自动跟踪 unstable 中的特定软件包,而无需初始 “-t unstable” 安装,则必须创建 “/etc/apt/preferences” 文件,并在其顶部显式列出所有这些软件包,如下所示。

Package: <package-1>
Pin: release a=unstable
Pin-Priority: 700

Package: <package-2>
Pin: release a=unstable
Pin-Priority: 700

这些设置了每个特定软件包的 Pin-Priority 值。 例如,为了跟踪英文版 “Debian 参考手册” 的最新 unstable 版本,您应该在 “/etc/apt/preferences” 文件中包含以下条目。

Package: debian-reference-en
Pin: release a=unstable
Pin-Priority: 700

Package: debian-reference-common
Pin: release a=unstable
Pin-Priority: 700
[Tip] 提示

即使您正在跟踪 stable 存档,此 apt-pinning 技术也有效。 到目前为止,根据我的经验,从 unstable 存档安装文档软件包一直很安全。

2.7.7. 使用来自 experimental 的一些软件包跟踪 unstable

这是另一个 apt-pinning 技术的示例,用于包含在跟踪 unstable 时在 experimental 中找到的特定较新上游版本软件包。 您需要在 “/etc/apt/sources.list” 文件中列出所有必需的存档,如下所示。

deb http://ftp.us.debian.org/debian/ unstable main contrib non-free
deb http://ftp.us.debian.org/debian/ experimental main contrib non-free
deb http://security.debian.org/ testing/updates main contrib

experimental 存档的默认 Pin-Priority 值始终为 1 (<<100),因为它是 NotAutomatic 存档(请参阅 第 2.5.3 节,“存档级别 "Release" 文件”)。 除非您希望自动跟踪其中的特定软件包以进行下一次升级,否则无需在 “/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 系统的风险小于入侵者利用安全漏洞(该漏洞已通过安全更新关闭)破坏系统的风险,则应考虑使用此自动升级并使用以下配置参数。

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

如果您正在运行 unstable 系统,则不希望使用自动升级,因为它肯定会在某一天破坏系统。 即使对于这种 unstable 情况,您可能仍然希望提前下载软件包,以节省交互式升级的时间,并使用以下配置参数。

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

2.7.9. 限制 APT 的下载带宽

如果您想将 APT 的下载带宽限制为例如 800Kib/秒(=100kiB/秒),您应该使用以下配置参数配置 APT。

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

2.7.10. 紧急降级

[Caution] 注意

Debian 在设计上不支持降级。 它应该仅作为紧急恢复过程的一部分完成。 尽管存在这种情况,但众所周知,它在许多事件中都能很好地工作。 对于关键系统,您应该在恢复操作后备份系统上的所有重要数据,并从头开始重新安装新系统。

您可能很幸运地从较新的存档降级到较旧的存档,以通过操作 候选版本 从损坏的系统升级中恢复(请参阅 第 2.7.3 节,“调整候选版本”)。 这是许多 “dpkg -i <broken-package>_<old-version>.deb” 命令(请参阅 第 2.6.4 节,“使用 dpkg 命令救援”)的繁琐操作的懒惰替代方案。

在 “/etc/apt/sources.list” 文件中搜索跟踪 unstable 的行,如下所示。

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

将其替换为以下内容以跟踪 testing

deb http://ftp.us.debian.org/debian/ wheezy main contrib non-free

将 “/etc/apt/preferences” 文件设置为如下所示。

Package: *
Pin: release a=testing
Pin-Priority: 1010

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

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

[Tip] 提示

最好删除(而不是清除!)尽可能多的软件包,以最大限度地减少依赖关系问题。 您可能需要手动删除和安装一些软件包才能使系统降级。 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 作为最后的手段来满足缺少的软件包依赖性。

Package: equivs
Priority: extra
Section: admin
Description: Circumventing Debian package dependencies
 This is a dummy package which can be used to create Debian
 packages, which only contain dependency information.

2.7.13. 将软件包移植到 stable 系统

对于 stable 系统的部分升级,最好在其环境中使用源代码软件包重新构建软件包。 这避免了由于依赖关系而导致的大规模软件包升级。

将以下条目添加到 stable 系统的 “/etc/apt/sources.list” 中。

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

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

# apt-get update
# apt-get dist-upgrade
# apt-get install fakeroot devscripts build-essential
$ apt-get build-dep foo
$ apt-get source foo
$ cd foo*

根据需要调整已安装的软件包。

执行以下操作。

$ dch -i

增加软件包版本,例如在 “debian/changelog” 中附加 “+bp1” 的版本

构建软件包并将其安装到系统中,如下所示。

$ debuild
$ cd ..
# 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 存档的代理工具列表

软件包 popcon 大小 描述
approx http://qa.debian.org/popcon.php?package=approx 3537 Debian 存档文件的缓存代理服务器(编译后的 OCaml 程序)
apt-cacher http://qa.debian.org/popcon.php?package=apt-cacher 311 Debian 软件包和源文件的缓存代理(Perl 程序)
apt-cacher-ng http://qa.debian.org/popcon.php?package=apt-cacher-ng 1132 软件发行版的缓存代理(编译后的 C++ 程序)
debtorrent http://qa.debian.org/popcon.php?package=debtorrent 1185 用于下载 Debian 软件包的 Bittorrent 代理(Python 程序)

[Caution] 注意

当 Debian 重新组织其存档结构时,这些专门的代理工具往往需要软件包维护者重写代码,并且可能会在一段时间内无法正常工作。 另一方面,通用 Web (http) 代理服务器更健壮,更容易应对此类更改。

2.7.15. 小型公共软件包存档

这是一个示例,用于创建与现代 安全 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 存档密钥,如下所示。

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

发布存档密钥文件 “foo.public.key”,密钥 ID 为 “3A3CB5A6”,用于 Foo

创建名为 “Origin: Foo” 的存档树,如下所示。

$ umask 022
$ mkdir -p ~/public_html/debian/pool/main
$ mkdir -p ~/public_html/debian/dists/unstable/main/binary-amd64
$ mkdir -p ~/public_html/debian/dists/unstable/main/source
$ cd ~/public_html/debian
$ cat > dists/unstable/main/binary-amd64/Release << EOF
Archive: unstable
Version: 4.0
Component: main
Origin: Foo
Label: Foo
Architecture: amd64
EOF
$ cat > dists/unstable/main/source/Release << EOF
Archive: unstable
Version: 4.0
Component: main
Origin: Foo
Label: Foo
Architecture: source
EOF
$ cat >aptftp.conf <<EOF
APT::FTPArchive::Release {
  Origin "Foo";
  Label "Foo";
  Suite "unstable";
  Codename "sid";
  Architectures "amd64";
  Components "main";
  Description "Public archive for Foo";
};
EOF
$ cat >aptgenerate.conf <<EOF
Dir::ArchiveDir ".";
Dir::CacheDir ".";
TreeDefault::Directory "pool/";
TreeDefault::SrcDirectory "pool/";
Default::Packages::Extensions ".deb";
Default::Packages::Compress ". gzip bzip2";
Default::Sources::Compress "gzip bzip2";
Default::Contents::Compress "gzip bzip2";

BinDirectory "dists/unstable/main/binary-amd64" {
  Packages "dists/unstable/main/binary-amd64/Packages";
  Contents "dists/unstable/Contents-amd64";
  SrcPackages "dists/unstable/main/source/Sources";
};

Tree "dists/unstable" {
  Sections "main";
  Architectures "amd64 source";
};
EOF

您可以通过配置 dupload 来自动化服务器系统上 APT 存档内容的重复更新。

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

$cfg{'foo'} = {
  fqdn => "www.example.com",
  method => "scpb",
  incoming => "/home/foo/public_html/debian/pool/main",
  # The dinstall on ftp-master sends emails itself
  dinstall_runs => 1,
};

$cfg{'foo'}{postupload}{'changes'} = "
  echo 'cd public_html/debian ;
  apt-ftparchive generate -c=aptftp.conf aptgenerate.conf;
  apt-ftparchive release -c=aptftp.conf dists/unstable >dists/unstable/Release ;
  rm -f dists/unstable/Release.gpg ;
  gpg -u 3A3CB5A6 -bao dists/unstable/Release.gpg dists/unstable/Release'|
  ssh foo@www.example.com  2>/dev/null ;
  echo 'Package archive created!'";

dupload(1) 启动的 postupload 钩子脚本为每次上传创建更新的存档文件。

您可以通过以下方式将此小型公共存档添加到客户端系统的 apt 行。

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

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

2.7.16. 记录和复制系统配置

您可以通过以下方式制作软件包和 debconf 选择状态的本地副本。

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

在此,“*” 使 “selection.dpkg” 也包含 “purge”(清除)的软件包条目。

您可以将这两个文件传输到另一台计算机,并在那里使用以下命令安装。

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

如果您正在考虑在集群中管理许多配置几乎相同的服务器,则应考虑使用专用软件包(例如 fai)来管理整个系统。

2.7.17. 转换或安装 alien 二进制软件包

alien(1) 允许将 Red Hat rpm、Stampede slp、Slackware tgz 和 Solaris pkg 文件格式提供的二进制软件包转换为 Debian deb 软件包。 如果您想使用来自另一个 Linux 发行版的软件包,而不是您系统上安装的发行版,您可以使用 alien 将其从您喜欢的软件包格式转换为 Debian 软件包并安装它。 alien 也支持 LSB 软件包。

[Warning] 警告

alien(1) 不应用于替换重要的系统软件包,例如 sysvinitlibc6libpam-modules 等。 实际上,alien(1) 应该仅用于 非自由 的纯二进制软件包,这些软件包符合 LSB 标准或静态链接。 对于自由软件,您应该使用其源代码软件包来制作真正的 Debian 软件包。

2.7.18. 在不使用 dpkg 的情况下提取软件包

可以使用标准 ar(1)tar(1) 在任何 类 Unix 环境中提取当前的 “*.deb” 软件包内容,而无需使用 dpkg(1)

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

您还可以使用 mc 命令浏览软件包内容。

2.7.19. 有关软件包管理的更多阅读材料

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