理解 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-getapt-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:类似于 dpkgrpm 是用于 .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 upgradesudo dnf update 以应用安全补丁和错误修复。
  • 安装前了解:在安装之前,始终检查软件包的功能和声誉,尤其是来自第三方仓库的软件包。
  • 验证仓库源:确保添加的任何仓库都是可信的,以防止安装恶意或不稳定的软件。
  • 清理:使用 sudo apt autoremovesudo dnf autoremove 删除孤立的依赖关系并释放磁盘空间。
  • 查看 apt showdnf 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 upgradesudo 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 -Srpm -qf 会告诉你它属于哪个包。如果没有包拥有它,该文件可能是由应用程序、部署脚本、管理员或攻击者创建的。这本身并不能证明什么,但它为你提供了一个更好的下一步问题。

关于包管理最安全的思考方式很简单:坚持使用你的发行版期望的工具,在接受之前阅读事务,并将第三方仓库视为生产依赖项。一旦你知道仓库文件的位置以及如何检查包所有权,APT、YUM 和 DNF 感觉就不那么像不同的世界了。