理解 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 感觉就不那么像不同的世界了。