理解 Linux 包管理:APT vs. YUM vs. DNF
APT、YUM 和 DNF 在安装、更新、删除和故障排除 Linux 软件包方面的实用比较。
理解 Linux 包管理:APT vs. YUM vs. DNF
如果你在 Ubuntu、Debian、Fedora、Rocky Linux、AlmaLinux 或 RHEL 之间切换,包管理是第一个让你感到肌肉记忆失效的地方。任务在任何地方都一样:安装软件、应用安全更新、删除不再需要的内容,并保持依赖关系一致。命令和文件位置差异足够大,以至于复制错误的操作手册可能会浪费时间或损坏主机。
APT、YUM 和 DNF 并不是你通常在一台机器上选择的竞争工具。它们属于不同的发行版家族。APT 是基于 Debian 的系统上常见的高级工具。YUM 是较旧的基于 Red Hat 的系统上长期使用的高级工具。DNF 是当前 Fedora、RHEL 8 及更新版本、CentOS Stream、Rocky Linux 和 AlmaLinux 上的现代替代品。
什么是包管理器?
本质上,包管理器是一组软件工具,用于自动化从操作系统安装、升级、配置和删除软件包的过程。包管理器不是从源代码编译软件或手动管理依赖关系,而是与软件仓库交互,获取预编译的二进制文件并自动处理所有必要的先决条件。
包管理器的关键功能包括:
- 依赖关系解析:自动识别并安装特定应用程序运行所需的所有库和其他软件包。
- 软件仓库:管理与远程服务器(仓库)的连接,这些服务器存储软件包,确保访问广泛的软件。
- 系统升级:促进单个软件包或整个操作系统的更新,确保应用安全补丁和新功能。
- 包完整性:使用数字签名验证软件包的真实性和完整性,防止篡改。
- 干净卸载:确保卸载软件时,所有相关文件和依赖关系被干净地删除,避免系统混乱。
Linux 发行版通常使用两种主要的包格式之一:基于 Debian 的系统使用 .deb,基于 Red Hat 的系统使用 .rpm。APT 管理 .deb 包,而 YUM 和 DNF 管理 .rpm 包。
APT(高级包工具)
APT 是用于管理 .deb 包的命令行工具,主要出现在 Debian 及其衍生版上,如 Ubuntu、Linux Mint、Pop!_OS 等。它以其强大的依赖关系解析和庞大的软件生态系统而闻名。
核心概念
dpkg:虽然apt是高级工具,但dpkg是底层低级工具,实际安装、删除和管理单个.deb包。APT 作为dpkg的前端,处理仓库和依赖关系。sources.list:/etc/apt/sources.list文件(以及/etc/apt/sources.list.d/中的文件)定义了 APT 用于查找软件包的软件仓库位置。这些可以是官方仓库、第三方 PPA(个人包存档)或本地源。- 包结构:软件包以
.deb文件形式分发,这些文件本质上是包含编译软件、配置文件和元数据的存档。
常见 APT 命令
历史上,apt-get 是主要命令,但 apt 命令(在 Debian 8 / Ubuntu 16.04 左右引入)通过结合 apt-get 和 apt-cache 的最常见功能,提供了更友好的用户界面。
| 任务 | apt 命令 |
描述 |
|---|---|---|
| 更新包列表 | sudo apt update |
从仓库刷新可用软件包及其版本的列表。 |
| 升级已安装的包 | sudo apt upgrade |
将所有已安装的软件包升级到最新版本。不删除包。 |
| 完整系统升级 | sudo apt full-upgrade |
升级所有已安装的包,必要时删除旧包以解决依赖关系。 |
| 安装包 | sudo apt install <package_name> |
安装指定的包及其依赖关系。 |
| 删除包 | sudo apt remove <package_name> |
删除包但保留其配置文件。 |
| 清除包 | sudo apt purge <package_name> |
删除包及其配置文件。 |
| 搜索包 | apt search <keyword> |
搜索匹配关键字的包。 |
| 显示包详细信息 | apt show <package_name> |
显示包的详细信息。 |
| 清理旧包 | sudo apt autoremove |
删除不再需要的自动安装的依赖包。 |
示例
# 更新包列表
sudo apt update
# 安装 'nginx' 网络服务器
sudo apt install nginx
# 升级所有已安装的包
sudo apt upgrade
# 删除 'nginx' 及其配置文件
sudo apt purge nginx
APT 的优点
- 可靠的依赖处理:APT 擅长在更改系统之前解释它计划安装、升级、保留或删除的内容。
- 庞大的仓库生态系统:Debian 和 Ubuntu 仓库涵盖广泛的服务器和桌面软件。
- 可预测的服务器行为:稳定的 Debian 和 Ubuntu LTS 版本通常优先考虑经过测试的包版本,而不是最新的上游版本。
APT 的缺点
- 较新的软件版本:有时,官方仓库中的包可能不是绝对最新的版本,因为注重稳定性和彻底测试。
YUM(Yellowdog 更新器,修改版)
YUM 是 Red Hat Enterprise Linux (RHEL) 及其衍生版(如 CentOS、Fedora(直到最近)和 Scientific Linux)的主要包管理器。它操作 .rpm(Red Hat 包管理器)包。
核心概念
rpm:类似于dpkg,rpm是用于.rpm文件的低级包管理工具。YUM 作为更高级的前端。.repo文件:仓库配置通常在/etc/yum.repos.d/中的.repo文件中定义。这些文件指定每个仓库的基本 URL、GPG 密钥和其他元数据。- 包结构:软件以
.rpm文件形式分发,包含二进制文件、库和元数据。
常见 YUM 命令
| 任务 | yum 命令 |
描述 |
|---|---|---|
| 检查更新 | sudo yum check-update |
检查可用更新而不安装它们。 |
| 更新所有包 | sudo yum update |
更新所有已安装的包。 |
| 安装包 | sudo yum install <package_name> |
安装指定的包及其依赖关系。 |
| 删除包 | sudo yum remove <package_name> |
删除包。 |
| 搜索包 | yum search <keyword> |
搜索匹配关键字的包。 |
| 显示包详细信息 | yum info <package_name> |
显示包的详细信息。 |
| 清理缓存文件 | sudo yum clean all |
清理缓存的仓库元数据和包。 |
示例
# 检查可用更新
sudo yum check-update
# 安装 'httpd'(Apache)网络服务器
sudo yum install httpd
# 更新所有已安装的包
sudo yum update
# 删除 'httpd'
sudo yum remove httpd
YUM 的优点
- 成熟的企业行为:YUM 在较旧的 RHEL 和 CentOS 系统上仍然常见,因此你会在遗留操作手册中看到它。
- 事务历史:
yum history可以显示以前的安装、更新和删除。在某些情况下,你可以撤消或回滚事务,但应谨慎测试,因为配置文件、服务状态和外部数据不会神奇地恢复。
YUM 的缺点
- 性能:有时可能比现代包管理器(如 DNF)慢,尤其是在大型仓库或复杂依赖树的情况下。
- 正在被取代:在较新的基于 RHEL 的系统(RHEL 8+)中,DNF 已取代 YUM 成为默认包管理器,尽管
yum通常仍然作为dnf的别名工作。
DNF(Dandified YUM)
DNF 是基于 Red Hat 的发行版的下一代包管理器,是 YUM 的继任者。它是 Fedora(自版本 18 起)、RHEL 8+、CentOS Stream、AlmaLinux 和 Rocky Linux 的默认包管理器。DNF 解决了 YUM 的许多缺点,提供了改进的性能和依赖关系解析。
核心概念
libsolv:DNF 使用libsolv进行依赖关系解析,该工具高度优化,比 YUM 的旧解析器提供显著更好的性能。- 模块化:RHEL 8+ 和 Fedora 中的一个关键特性,模块化允许同一软件包的不同版本或流(例如,Python 3.6 与 Python 3.8)同时可用,用户可以选择安装哪一个。
- 兼容性:DNF 维护一个与 YUM 基本兼容的命令行界面,使用户更容易过渡。
常见 DNF 命令
许多 DNF 命令与 YUM 命令相同或非常相似。
| 任务 | dnf 命令 |
描述 |
|---|---|---|
| 检查更新 | sudo dnf check-update |
检查可用更新而不安装它们。 |
| 更新所有包 | sudo dnf update |
更新所有已安装的包。 |
| 安装包 | sudo dnf install <package_name> |
安装指定的包及其依赖关系。 |
| 删除包 | sudo dnf remove <package_name> |
删除包。 |
| 搜索包 | dnf search <keyword> |
搜索匹配关键字的包。 |
| 显示包详细信息 | dnf info <package_name> |
显示包的详细信息。 |
| 清理缓存文件 | sudo dnf clean all |
清理缓存的仓库元数据和包。 |
| 列出可用模块 | dnf module list |
列出可用的软件模块流。 |
| 启用模块 | sudo dnf module enable <module> |
启用特定的模块流。 |
示例
# 检查可用更新
sudo dnf check-update
# 安装 'mariadb-server' 数据库
sudo dnf install mariadb-server
# 更新所有已安装的包
sudo dnf update
# 列出可用的 Node.js 模块流
dnf module list nodejs
# 启用 Node.js 16 模块流(如果可用)
sudo dnf module enable nodejs:16
# 删除 'mariadb-server'
sudo dnf remove mariadb-server
DNF 的优点
- 改进的依赖解决:DNF 使用
libsolv,通常比旧的 YUM 行为更快、更清晰地处理复杂的依赖选择。 - 更清晰的输出和 API:在许多管理工作流程中,DNF 比旧版 YUM 更容易编写脚本。
- 模块化:提供在同一系统内安装不同版本软件的灵活性。
- 现代设计:使用清晰的 API 进行扩展和更干净的代码构建。
DNF 的缺点
- 较新的技术:虽然稳定,但某些功能,尤其是与模块化相关的功能,可能对新用户来说需要稍陡的学习曲线。
主要区别和用例
APT 与 YUM/DNF 之间的根本区别在于它们服务的发行版家族以及它们处理的包格式。
| 特性 | APT(Debian/Ubuntu) | YUM/DNF(RHEL/Fedora) |
|---|---|---|
| 包格式 | .deb(Debian 包) |
.rpm(Red Hat 包) |
| 底层工具 | dpkg |
rpm |
| 配置文件 | /etc/apt/sources.list |
/etc/yum.repos.d/*.repo |
| 主要发行版 | Debian, Ubuntu, Mint, Pop!_OS | RHEL, Fedora, CentOS, AlmaLinux, Rocky Linux |
| 依赖解析器 | 内部(稳健,经过充分测试) | YUM:内部(较慢);DNF:libsolv(更快,现代) |
| 演变 | apt-get -> apt |
yum -> dnf |
| 模块化 | 未直接内置(PPA 提供灵活性) | DNF 提供 module 流用于多个版本 |
- APT 适用于优先考虑坚如磐石的稳定性、广泛的社区支持和庞大软件仓库的用户和管理员。它是基于 Debian 的系统的首选,这些系统在服务器和桌面领域都很受欢迎。
- YUM 多年来在企业环境中很好地发挥了作用,提供了一种稳定且经过验证的软件管理方法。虽然仍然作为别名存在,但其直接使用正在逐步淘汰。
- DNF 是基于 Red Hat 的系统的现代标准。它是运行现代 RHEL、Fedora 或其衍生版的用户的选择,提供性能、高级依赖关系解析和模块化等功能,使其非常适合需要特定软件版本的开发和生成环境。
包管理的最佳实践
无论你使用哪个包管理器,遵循最佳实践可确保系统健康和安全:
- 定期更新:定期运行
sudo apt update && sudo apt upgrade或sudo dnf update以应用安全补丁和错误修复。 - 安装前了解:在安装之前,始终检查软件包的功能和声誉,尤其是来自第三方仓库的软件包。
- 验证仓库源:确保添加的任何仓库都是可信的,以防止安装恶意或不稳定的软件。
- 清理:使用
sudo apt autoremove或sudo dnf autoremove删除孤立的依赖关系并释放磁盘空间。 - 查看
apt show或dnf info:在安装之前,使用这些命令获取有关软件包的详细信息,包括其依赖关系和大小。 - 备份关键系统:在执行重大升级(例如
apt full-upgrade或发行版升级)之前,确保已备份关键数据和配置。
包管理器问题故障排除
大多数包管理器故障并不神秘,一旦你将它们分为三类:仓库元数据、依赖冲突和本地包数据库状态。
如果 APT 说找不到包,从 sudo apt update 开始。APT 不会为每次安装都查询每个远程仓库。它使用本地元数据。如果包是最近添加的,或者机器有一段时间没有刷新其列表,即使仓库正确,安装也可能失败。如果 apt update 本身失败,请阅读错误中的仓库行。过时的 PPA、过期的签名密钥、损坏的镜像或不支持的发行版代号通常是真正的问题。
在 DNF 或 YUM 系统上,等效的第一步通常是:
sudo dnf makecache
sudo dnf repolist
在较旧的系统上:
sudo yum makecache
sudo yum repolist
repolist 很有用,因为它确认仓库是否已启用。包可能来自 EPEL、CodeReady Builder、PowerTools、CRB 或供应商仓库,而不是基础 OS 仓库。在这种情况下,修复方法不是从网上下载随机 RPM。更干净的修复方法是启用正确的仓库,让包管理器处理依赖关系。
依赖冲突需要更小心。如果 APT 建议删除系统的大部分内容,请停止并阅读事务。dnf remove 也是如此。删除包可能会删除依赖它的服务。在服务器上,我喜欢在接受之前将建议的事务复制到事件记录中。如果之后服务中断,这可以为你提供更改的记录。
对于中断的安装,在尝试手动清理之前,使用本机修复命令:
# Debian/Ubuntu
sudo dpkg --configure -a
sudo apt -f install
# Fedora/RHEL-family
sudo dnf check
sudo dnf history
手动删除 /var/lib/dpkg、/var/lib/rpm、/var/cache/apt 或 /var/cache/dnf 下的内容应该是最后的手段。这些目录是包管理器状态,而不是普通杂物。
实用翻译速查表
当你遵循为不同 Linux 家族编写的文档时,翻译意图,而不仅仅是命令。
| 任务 | Debian/Ubuntu | Fedora/RHEL-family |
|---|---|---|
| 刷新仓库元数据 | sudo apt update |
sudo dnf makecache |
| 升级已安装的包 | sudo apt upgrade |
sudo dnf upgrade 或 sudo dnf update |
| 安装包 | sudo apt install nginx |
sudo dnf install nginx |
| 删除包 | sudo apt remove nginx |
sudo dnf remove nginx |
| 删除包和配置 | sudo apt purge nginx |
无完全等效;包脚本可能留下配置/数据 |
| 搜索包 | apt search nginx |
dnf search nginx |
| 显示包信息 | apt show nginx |
dnf info nginx |
| 列出已安装的包 | apt list --installed |
dnf list installed |
| 查看包文件 | dpkg -L nginx |
rpm -ql nginx |
| 查找文件所属包 | dpkg -S /path/file |
rpm -qf /path/file |
最后一对被低估了。如果你在主机上发现一个奇怪的二进制文件或配置文件,dpkg -S 或 rpm -qf 会告诉你它属于哪个包。如果没有包拥有它,该文件可能是由应用程序、部署脚本、管理员或攻击者创建的。这本身并不能证明什么,但它为你提供了一个更好的下一步问题。
关于包管理最安全的思考方式很简单:坚持使用你的发行版期望的工具,在接受之前阅读事务,并将第三方仓库视为生产依赖项。一旦你知道仓库文件的位置以及如何检查包所有权,APT、YUM 和 DNF 感觉就不那么像不同的世界了。