Skip to content

APT

Debian 建立了一致的自由软件的预编译二进制包并从档案库中分发他们。并使用 apt(Advanced package tool) 来使用这些资源,底层这使用 dpkg(Debian Package) 来管理这些二进制包。他们共同作用组成了目前的 Debian 软件包管理系统。

相关管理工具

核心工具:

  • dpkg: 底层工具,面向二进制包来进行安装、卸载等操作
  • apt: 前端工具,用于与档案库进行交互以及处理二进制包中的依赖

工具集:

  • apt-file: 用于搜索 apt 软件包内所包含文件的命令行工具。用于搜索某个文件由哪个软件包提供,或者列出软件包包含哪些文件

前端工具:

Debian 档案库

所谓的档案库实际上就是一个中心化的软件包仓库。他们被定义在/etc/apt/sources.list配置文件中,一个典型的内容如下:

Bash
deb http://deb.debian.org/debian/ bookworm main non-free-firmware contrib non-free
deb-src 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-src http://security.debian.org/debian-security bookworm-security main non-free-firmware contrib non-free
  • deb/deb-src: 定义二进制包还是源码包
  • http://...: 定义档案库的根 url
  • bookworm: 指定套件名称(suite name)或者发行版代号(codename)
  • main no-free-firmware contrib non-free: 指定档案库的有效范围

Debian 的发行版代号都是玩具总动员中的名称,不稳定版本(unstable)永久使用代号 sid,他也是玩具总动员的玩具破坏者

发行版代号

档案库 URL 套件名称(发行版代号) 目的
http://deb.debian.org/debian/ stable (bookworm) stable (bookworm) release 版本
http://deb.debian.org/debian/ testing (trixie) testing (trixie) release 版本
http://deb.debian.org/debian/ unstable (sid) unstable (sid) release 版本
http://deb.debian.org/debian/ experimental experimental pre-release 版本(可选,只适用于开发者)
http://deb.debian.org/debian/ stable-proposed-updates (bookworm-proposed-updates) 用于下一个稳定版 (bookworm)点版本(小版本)发布的更新(可选)
http://deb.debian.org/debian/ stable-updates(bookworm-updates) 用于稳定版( bookworm )的垃圾邮件过滤器、IM客户端等的兼容更新
http://deb.debian.org/debian/ stable-backports (bookworm-backports) 用于稳定版(bookworm ) 的较新的向后移植的软件包(可选)
http://security.debian.org/debian-security/ stable-security (bookworm-security) 用于稳定版(bookworm) 发布的安全更新(重要)
http://security.debian.org/debian-security/ testing-security (trixie-security) 用于测试版发布的安全更新(这个没有安全团队的积极支持)

官方源通常比较慢,可以在 mirror-list 中查看国内源来更换。需要注意的是安全更新并不在档案库中,而是位于 security.debian.org 下,官方推荐不要更改他,不过在国内这个非常慢通常需要换国内源

如何选择

新发布的 stable 软件通常是比较新的,不过一旦发布就不会有大的变动了,如果为了获取较新的兼容软件包可以开启 stable-backports。他们会在保持兼容的情况下提供最新版本的支持。

testing 作为下一代发行版的预先测试版,只有 unstable 被完全测试后会进入 testing 中。如果追求常用尝新(例如个人桌面),只要保护好私人数据,使用 testing 也是一个非常好的选择。

官方推荐只有测试人员才应当启用 unstable,他可以看作是滚动发布的版本,尽管可能没有 arch 那么激进。当然大多数时候他是稳定的。

如果有多个只有档案库可用,越新的优先级越高(例如 unstable 是优先级最高的)。安全更新在 unstable 下没有意义,实际上 testing-security 意义也不大。

混用 stable 和 testing 或 unstable 包的风险是最大的。因此尽可能只开启一个。哪怕是 unstable

档案库的范围

区域 软件包数量 软件包组件标准
main 72806 遵从 Debian 自由软件指导方针(DFSG),并且不依赖于 non-free
non-free-firmware 39 不符合 Debian 自由软件指导方针(DFSG),正常的系统安装过程中必需要用到的固件
contrib 356 遵从 Debian 自由软件指导方针(DFSG),但依赖于 non-free
non-free 964 不遵从 Debian 自由软件指导方针(DFSG),并且不在 non-free-firmware

档案库元数据

http://deb.debian.org/debian 即 debian 的档案库,其中包含一个dist/文件夹,该文件夹下包含了每个目前还提供支持的发行版的元数据。所谓的元数据可以简单理解为描述性信息:

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

看起来比较抽象,实际上一切结构都是为了两个目的:

  1. 能够让用户更方便的搜索需要安装的包
  2. 让用户安装的包一定是官方包(通过 hash 保证)

顶层 Release 文件的真实性保证

顶层 Release 中的内容是:

Bash
# md5 文件大小 文件路径
884daf4d162ab8b826335c17a48bfea6 503512242 main/Contents-all
1d2f0ad7a84fd2897b170202ea6bafa5 32948493 main/Contents-all.gz
# ...

说白了 Release 文件是保证dist/目录下文件的完整性,即元信息的完整性,而为了保证 Release 没有问题就提供了 Release.gpg 来保证。

软件包元信息

disk/目录下包含了main/ contrib/ no-free-firmware/ non-free/这四个定义范围的目录,其中的Contents-<arch>中定义了对应架构的所有文件以及对应的安装包,内容如下:

Bash
# 以字母表排序的
bin/bash                                                shells/bash
bin/bash-static                                         shells/bash-static
bin/brltty                                              admin/brltty
#...
etc/fonts/conf.d/README                                 fonts/fontconfig-config
etc/fonts/fonts.conf                                    fonts/fontconfig-config
etc/foremost.conf                                       admin/foremost

每个区域的路径下都包含binary-<arch>目录,该目录下会包含一个 Packages 文件,其中定义了二进制包(deb)的简要信息:

Text Only
Package: python3-pymongo
Source: pymongo (3.11.0-1)
Version: 3.11.0-1+b5
Installed-Size: 1130
Maintainer: Federico Ceratto <federico@debian.org>
Architecture: amd64
Depends: python3-bson (= 3.11.0-1+b5), python3:any
Recommends: python3-gridfs (>= 3.11.0-1), python3-pymongo-ext
Suggests: python-pymongo-doc
Description: Python3 interface to the MongoDB document-oriented database
Homepage: https://api.mongodb.org/python/
Description-md5: 6f125b3a0ac150b7b1c36d15734940e4
Section: python
Priority: optional
Filename: pool/main/p/pymongo/python3-pymongo_3.11.0-1+b5_amd64.deb
Size: 210400
MD5sum: e9898dbb3d39222f9f4e67c01f5af949
SHA256: c772ec95c6583ef4d6ecb24068766e2b5bdd4c70f306067347b83650a049fde7

其中包含了该包的 Hash 信息,最重要的是包含了文件所在的, apt 命令会从pool/(与dist/同目录) 文件夹中去下载二进制包。 区域路径下面还包含一些其他文件夹,其中debian-installer/是在 debian 安装界面可用的二进制包(udeb)。i18n/是本地化内容。source/是源码包。

缓存档案库元数据

当使用 apt 工具时,需要更新包含 Debian 档案库的元信息(就是dist/中的内容)缓存到本地。这部分内容的路径以及命名方式:

Bash
# 对应的就是版本库路径
# dists/<distribution>/Release
# dists/<distribution>/Release.gpg
# dists/<distribution>/<area_binary-architecture>/Packages
"/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"
# apt-file
"/var/cache/apt/apt-file/deb.debian.org_debian_dists_distribution_Contents-architecture.gz"

apt_preferences

/etc/apt/sources.list中定义了要开启的软件源,说白了就是从dist/下的对应目录找到对应的元数据,之后在元数据中搜索可用的二进制包来安装。而sources.list定义的内容如何在 dist 中定位就是由每个目录中的Release决定:

Bash
# dist/Release
Origin: Debian
Label: Debian
Suite: stable
Version: 12.1
Codename: bookworm
# dist/<Codename>/<area_binary>/Release
Archive: stable
Origin: Debian
Label: Debian
Version: 12.1
Acquire-By-Hash: yes
Component: main
Architecture: amd64

其他信息

apt 在使用过程中还会记录一些其他信息:

Bash
# 追踪自动安装的所有软件包的状态信息
/var/lib/apt/extended_states
# 缓存目录
/var/cache/apt/archives/

软件包管理

Debian 下软件包管理包含众多工具,不过面向用户的核心工具就是 apt 以及相关的工具集。其中最常用的有:

  • apt-get:与远程的档案库交互(下载、更新等)
  • apt-cache:与本地的缓存库交互(主要是搜索缓存或者搜索已安装文件)
  • apt-file:实际上就是与Contents-architecture文件交互,查询文件所属包或包包含的文件内容

目前使用 apt 命令整合了 apt-get 和 apt-cache 并提供了更加友好的进度条。apt-get 和 apt-cache 现在更多的是使用在脚本中

软件包管理事件流

一个标准的软件包管理事件流如下:

事件流 命令 含义
更新 apt update 从远程档案库获取元数据并重建本地元数据(注意不实际更新包)
升级 apt upgrade 将所有安装包升级到最新可用版本
搜索 apt search <regex> 搜索软件包
包信息 apt show package_name 显示包的详细信息(就是 Package 中的内容)
安装 apt install <package_name> 安装指定二进制包
移除 apt remove <package_name> 移除对应的软件包,可以指定--purge来删除配置文件
清除 apt purge <package_name> 清除软件包配置文件(remove 默认不会删除他们)
自动移除 apt autoremove 移除不在需要的自动安装的软件包(依赖)
清除缓存 apt clean 清除已经移除的包的本地缓存(即 deb)
清除所有缓存 apt autoclean 清除所有包的本地缓存(即 deb),如果要腾出磁盘空间
列出软件包 apt list 默认列出所有软件包,可以指定--installed来筛选已经安装的包,--manual-installed筛选手动安装的包

跨版本升级需要使用 apt full-upgrade

apt-file

他的用法非常简单:

Bash
# 列出软件包包含的文件
apt-file list <package_name>
# 列出包含该文件的包
apt-file search <file-path>

他的本地操作由 dpkg 实现:

Bash
# 列出包包含的文件
dpkg -L <package_name>
# 列出对应文件属于哪个包
dpkg -S /path/to/file

软件包的高级管理

说来讽刺,对软件包的高级管理是通过低级的工具 dpkg 来完成的。dpkg 用来安装本地包,并且需要你手动来安装所需的依赖,这就导致了他并不好用,通常用户只需要使用 apt 就好了除非遇到 apt 无法解决的问题。

dpkg

dpkg 是 Debian 软件包管理中最底层的工具,当安装名为 package_name 的软件包时,dpkg 会按照下列的顺序处理它:

  1. 解包 deb 文件(等同于ar -x
  2. 使用 debconf 执行package_name.preinst
  3. 将软件包安装到系统中(等同于tar -x
  4. 使用 debconf 执行package_name.postinst

apt 是构建在 dpkg 之上的

救援

当由于软件包异常(通常是驱动)而导致的无法开机等,就必须使用 dpkg 这个底层工具了,此时可用从 U 盘启动 debian 之后将硬盘上的系统挂载到/target目录下,之后执行:

Bash
dpkg --root /target -i /path/to/foo_old_version_arch.deb

上面的命令可用在损坏的系统中安装指定包。

参考