Debian系统中的软件包管理是一个复杂而灵活的过程,涉及到多个工具和命令。首先,我们要理解的是高层的软件包管理工具,例如 aptitude 或 synaptic,它们依赖 apt,而 apt 又依赖 dpkg 来管理系统中的软件包。
一、上传软件包
尽管 “/var/lib/dpkg/available” 和 “/usr/share/doc/package_name/changelog” 中列出的维护者姓名提供了关于“软件包运作的幕后者是谁”这一问题的一些信息,但软件包的实际上传者依旧不明。devscripts 软件包中的 who-uploads(1) 可以识别 Debian 源软件包的实际上传者。
二、限制APT下载带宽
如果想限制 APT 的下载带宽到 800Kib/sec(=100KiB/sec),应该像下面那样设置 APT 的配置参数。
APT::Acquire::http::Dl-Limit "800";
三、自动下载/升级软件包
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";
如果运行的是 testing 或 unstable 系统,应该不会想要使用自动更新,因为它肯定会在某天损坏系统。即使位于这样的 testing 或unstable 情况下,可能依旧想提前下载软件包以节省交互式升级的时间,其配置参数如下。
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::Unattended-Upgrade "0";
四、更新和向后移植
stable-updates (“bookworm-updates”,在 bookworm-作为-stable 发布循环) 和 backports.debian.org 档案库提供了 stable 版软件包更新。为了去使用这些档案库,需要在 “/etc/apt/sources.list” 文件里写入如下所示的档案库列表。
deb http://deb.debian.org/debian/ bookworm main non-free-firmware contrib non-free deb http://security.debian.org/debian-security bookworm-security main non-free-firmware contrib non-free deb http://deb.debian.org/debian/ bookworm-updates main non-free-firmware contrib non-free deb http://deb.debian.org/debian/ bookworm-backports main non-free-firmware contrib non-free
- 并不需要在 “/etc/apt/preferences” 文件中显式设置Pin-Priority值. 当新的包可用时,默认配置提供了更合理的更新。
- 所有已安装的旧软件包都可以通过 bookworm-updates 档案库升级到新软件包。
- 只有从 bookworm-backports 档案库中手动安装的旧软件包才会通过 bookworm-backports 档案库升级到新软件包。
- 当想要从 bookworm-backports 档案库中手动的安装一个名叫 “package-name” 的软件及其依赖包的时候,应该在目标档案库之前加一个 “-t” 参数。
$ sudo apt-get install -t bookworm-backports package-name
不要从 backports.debian.org 档案库安装太多软件包。它能够造成软件包依赖复杂。
五、外部软件包档案库
应当小心,外部软件包获取系统的 root 权限。应当只使用可信赖的外部软件包档案库。能够使用安全 APT 来使用 Debian 兼容的外部软件包档案库,将它加入到 源列表,并把它的档案库密钥放入”/etc/apt/trusted.gpg.d/” 目录。参见 sources.list(5)、apt-secure(8) 和 apt-key(8)。
六、混合源档案库软件包
从混合源档案库中安装软件包是不被 Debian 官方发行版所支持的,除了官方支持的档案库的特殊组合以外,例如 stable 的 security updates 和 stable-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 的兼容性问题等等。
除非为了短期避免破坏软件包,从非 Debian 档案库安装二进制软件包通常是一个坏的主意。需要查找所有存在的和目前 Debian 系统兼容的安全技术替代方案。(参见 第 2.1.11 节 “怎样和不一致的要求协作”)。
七、使用apt-pinning
新手用 apt-pinning 命令会造成比较大的问题。必须避免使用这个命令除非确实需要它。
- 没有 “/etc/apt/preferences” 文件,APT 系统使用版本字符串来选择最新的可用版本作为 候选版本。这是通常的状态,也是 APT 系统最推荐的使用方法。所有官方支持的档案库集合,并不要求 “/etc/apt/preferences” 文件,因此,一些不应当被作为自动更新源的软件包,被标记为 NotAutomatic,并被适当处理。
- 版本字符串的比较规则可以被验证,例子如下,”dpkg –compare-versions ver1.1 gt ver1.1~1; echo $?”。
- 如果经常从混合源档案库中安装软件包, 可以通过创建 “/etc/apt/preferences” 文件并且在其中写入关于调整候选版本的软件包选取规则的合适条目 (如apt_preferences(5) 中所示)来自动化这些复杂的操作。这被称为 apt-pinning。
- 当使用 apt-pinning 命令时,因为 Debian 不会确保软件之间的兼容性,所以必须自己确认其兼容性。apt-pinning 是完全可选的操作,我并不建议去使用它。
- 档案库层级的 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 命令的情况下,也可以进行相当复杂的系统工作 。
如下是关于 apt-pinning 技术的简化说明:
可用的软件包源在 “/etc/apt/sources.list” 文件里面定义,APT 系统从可用的软件包源里面选择 Pin-Priority 值最大的,作为升级 软件包的候选版本。如果一个软件包的 Pin-Priority 大于 1000,这个版本限制为只能 升级,关闭了软件包降级功能。
每个软件包的 Pin-Priority 值是在 “/etc/apt/preferences” 文件中的 “Pin-Priority” 条目中定义或者是使用它的默认值。
用于 apt-pinning 技术的值得注意的 Pin-Priority 值列表:
Pin-Priority | apt-pinning 对软件包的影响 |
---|---|
1001 | 安装该软件包,即使是一个降级软件包的指令 |
990 | 用作目标发行版档案库的默认值 |
500 | 用作常规档案库的默认值 |
100 | 用于 NotAutomatic 和 ButAutomaticUpgrades 档案库的默认值 |
100 | 用于已安装软件包 |
1 | 用于 NotAutomatic 档案库的默认值 |
-1 | 即使被推荐,也绝不安装这个软件包 |
目标版本档案仓库,能够由命令行选项设置,例如: “apt-get install -t testing some-package”
NotAutomatic 和 ButAutomaticUpgrades 的档案是由档案库服务器上档案层级的 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/ bookworm-backports/main Packages”。
八、阻止软件包安装
如果不想要引入推荐的特定软件包,必须创建 “/etc/apt/preferences” 文件并且像如下所示的那样在文件的顶部明确列出这些软件包。
Package: package-1 Pin: version * Pin-Priority: -1 Package: package-2 Pin: version * Pin-Priority: -1
九、testing版本
新手用 apt-pinning 命令会造成比较大的问题。必须避免使用这个命令除非确实需要它。如下是一个关于 apt-pinning 技术的例子,当使用 testing的时候,实现 unstable 中的特定的较新的上游版本软件包的日常升级。应该按如下所示的在 “/etc/apt/sources.list” 文件中列出所有需要的档案库。
deb http://deb.debian.org/debian/ testing main contrib non-free deb http://deb.debian.org/debian/ unstable main contrib non-free deb http://security.debian.org/debian-security testing-security 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 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” 文件,并在该文件顶部按下面的方式清晰的列出所有那些软件包。
Package: package-1 Pin: release a=unstable Pin-Priority: 700 Package: package-2 Pin: release a=unstable Pin-Priority: 700
如下是为每个特定的软件包设置 Pin-Priority 值。例如,为了使用最新的 unstable 的英文版 “Debian Reference”,应该在 “/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
即使使用的是 stable 档案库,apt-pinning 技术仍然是有效的。根据我以前的经验,从 unstable 档案库安装的文档包一直是安全的。
十、unstable版本
新手用 apt-pinning 命令会造成比较大的问题。必须避免使用这个命令除非确实需要它。这是使用apt-pinning 的另一个示例,该示例主要使用unstable源,但包含了experimental源, 该源可用于安装上游更新的软件包 . 需要包含在”/etc/apt/sources.list” 文件中的列表如下:
deb http://deb.debian.org/debian/ unstable main contrib non-free deb http://deb.debian.org/debian/ experimental main contrib non-free deb http://security.debian.org/ testing-security main contrib
由于experimental源是 非自动(NotAutomatic)的源 (参见 第 2.5.3 节 “档案库层的“Release”文件”),其默认的Pin-Priority值 被设置为1 (<<100) . 并不需要在”/etc/apt/preferences”文件中设置Pin-Priority值,只需要指定 experimental 源,除非需要在下次更新时自动升级时更新特定软件包.
十一、紧急降级
新手用 apt-pinning 命令会造成比较大的问题。必须避免使用这个命令除非确实需要它。降级在 Debian 设计上就不被官方支持。仅仅是在紧急恢复过程中需要做的一部分工作。尽管憎恨这种情形,但降级在很多场景下工作得也不错。对于重要系统,应当在恢复操作后备份所有重要数据,并从零开始重新安装一个新的系统。
可以通过控制候选版本从新的档案库降级到旧的档案库(参见 第 2.7.7 节 “使用 apt-pinning 调整获选版本”),从而使损坏的系统恢复。下面是一种懒惰的方法,可以避免许多冗长的 “dpkg -i broken-package_old-version.deb” 命令(参见 第 2.6.6 节 “使用 dpkg 命令进行救援”)。
搜索 “/etc/apt/sources.list” 文件中像下面那样使用 unstable 的行。
deb http://deb.debian.org/debian/ sid main contrib non-free
使用下面的行替换它,从而改为使用 testing。
deb http://deb.debian.org/debian/ trixie main contrib non-free
按如下所示的设置 “/etc/apt/preferences” 文件。
Package: * Pin: release a=testing Pin-Priority: 1010
运行 “apt-get update; apt-get dist-upgrade” 使整个系统的软件包强制降级。在紧急降级后,移除 “/etc/apt/preferences” 这个特殊的文件。
十二、equivs软件包
如果从源代码编译了一个程序来代替 Debian 软件包,最好将它做成一个真正的本地 Debian 软件包(*.deb)并使用私人档案库。
如果选择从源代码编译一个程序并将它安装到 “/usr/local”,可能需要使用 equivs 作为最后步骤来满足缺失的软件包依赖。
Package: equivs Priority: optional Section: admin Description: Circumventing Debian package dependencies This package provides a tool to create trivial Debian packages. Typically these packages contain only dependency information, but they can also include normal installed files like other packages do. . One use for this is to create a metapackage: a package whose sole purpose is to declare dependencies and conflicts on other packages so that these will be automatically installed, upgraded, or removed. . Another use is to circumvent dependency checking: by letting dpkg think a particular package name and version is installed when it isn't, you can work around bugs in other packages' dependencies. (Please do still file such bugs, though.)
十三、移植软件包
由于系统差异,不能够保证这里描述的过程能够工作,而不需要额外的手工处理。对于部分升级的 stable 系统,使用源软件包在运行环境中重新构建一个软件包是不错的选择。这可以避免因为依赖关系导致大量软件包升级。在 stable 系统的 “/etc/apt/sources.list” 文件中添加下列条目。
deb-src http://deb.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*
如果需要向后移植,可以从 backport 的软件包中更新一些工具链软件包,例如 dpkg 和 debhelper。
执行下列命令:
$ dch -i
更新软件包版本,例如在 “debian/changelog” 中附加一个 “+bp1”像下面那样构建软件包并将它们安装到系统中。
$ debuild $ cd .. # debi foo*.changes
十四、APT代理服务器
因为镜像整个 Debian 档案库的子区会浪费硬盘和网络带宽,当管理许多 LAN 上的系统时,为 APT 部署一个本地代理服务器是个好主意。APT 可以通过配置来使用通用 web(http)代理服务器,例如 squid。环境变量 “$http_proxy 会覆盖 “/etc/apt/apt.conf” 文件中设置的代理服务器。
这里有一些 Debian 档案库的专用代理工具。应该在使用它们之前检查 BTS。
Debian 档案库的专用代理工具:
软件包 | 流行度 | 大小 | 说明 |
---|---|---|---|
approx |
V:0, I:0 | 7124 | 缓存 Debian 档案库文件的代理服务器(已编译的 OCaml 程序) |
apt-cacher |
V:0, I:0 | 266 | 为 Debian 软件包和源代码文件进行缓存代理(Perl 程序) |
apt-cacher-ng |
V:4, I:4 | 1816 | 分发软件包的缓存代理(C++ 编译的程序) |
当 Debian 重构它的档案库结构时,这些专用的代理工具往往需要软件包维护者重写代码,并可能在一段时间内无法使用。另一方面,通用 web (http) 代理服务器更强健并且更容易应对这种改变。