dnf 与 apt 不同的地方
一句话总结
dnf 最关键的不同之处在于:每次安装都会被记录为事务,并且可以撤销。apt 没有与之对应的功能。
为什么需要理解这一点
这是从 Ubuntu 转到 RHEL 系列系统的人最先感到意外的地方。
dnf history # 지금까지의 모든 트랜잭션 목록
dnf history info 42 # 42번 트랜잭션에서 무엇이 바뀌었나
dnf history undo 42 # 42번을 되돌린다
dnf history rollback 41 # 41번 시점의 상태로 되돌린다
apt 的 /var/log/apt/history.log 里虽然有记录,却没有用于撤销操作的命令。这一差异会改变运维方式。在 RHEL 系列系统上,可以“先安装试试,不合适再撤销”。
不过,它的局限也很明确。 如果仓库中已经没有旧版软件包,降级就会失败。而且 Red Hat 明确表示,不支持降级系统软件包(selinux、selinux-policy、kernel、glibc,以及依赖 glibc 的 gcc 等)。回滚并不是万能的。
它是如何工作的
命令对照表
| 操作 | apt | dnf |
|---|---|---|
| 更新索引 | apt-get update |
(自动完成,需要时运行 dnf makecache) |
| 安装 | apt-get install X |
dnf install X |
| 删除 | apt-get remove X |
dnf remove X |
| 搜索 | apt-cache search X |
dnf search X |
| 查看信息 | apt-cache show X |
dnf info X |
| 文件→软件包 | dpkg -S /path |
dnf provides /path(包括未安装的软件包) |
| 已安装文件列表 | dpkg -L X |
rpm -ql X |
| 升级 | apt-get upgrade |
dnf upgrade |
| 锁定版本 | apt-mark hold |
dnf versionlock add |
| 回滚 | 没有 | dnf history undo |
dnf provides 尤其强大。 apt 的 dpkg -S 只能查找已经安装的文件,而 dnf provides 会检索仓库元数据,连尚未安装的软件包也能找到。
dnf provides '*/nginx.conf'
dnf provides 'libnl-3.so.200()(64bit)'
第二个示例非常重要。在 RPM 中,依赖项的单位不是软件包名称,而是能力(capability)。共享库的 soname、文件路径,甚至符号版本都可以成为依赖目标。
dnf repoquery --requires httpd
dnf repoquery --requires --resolve --recursive httpd | sort -u | wc -l
--requires 表示所需的能力,--resolve 把该能力替换为提供它的软件包,而 --recursive 则继续递归查找。制作隔离网络导入清单时,它们是核心工具。
仓库文件
# /etc/yum.repos.d/labhub-local.repo
[labhub-local]
name=LabHub local (snapshot 2026-08-20)
baseurl=file:///srv/repo/labhub
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-labhub
metadata_expire=-1
理解每个键的默认值很重要。
enabled默认为 Truegpgcheck默认为 False——必须显式启用repo_gpgcheck(验证元数据签名)默认为 Falsepriority默认为 99metadata_expire默认为 48 小时。对于隔离网络中的本地仓库,最好设为-1(永不过期)module_hotfixes默认为 False
如果在仓库显示名称中写明快照日期,六个月后只需查看 dnf repolist -v 的一行输出,就能知道该服务器安装的是哪个时间点的内容。
缓存
隔离网络中最常见的报障是“软件包已经放进仓库,却还是看不到”。原因通常只有下面两个之一。
# 저장소 쪽: 메타데이터를 다시 만들었는가 (이걸 빼먹는 경우가 정말 많다)
createrepo_c --update /srv/repo/labhub
# 클라이언트 쪽: 캐시를 만료 표시 (가장 가벼움)
dnf clean expire-cache
# 그래도 안 되면
dnf clean metadata
# 최후의 수단
dnf clean all
dnf makecache
各操作的定义如下:expire-cache 只把元数据标记为过期,metadata 删除元数据,packages 删除缓存的软件包,而 all 删除全部缓存。
实际工作中会遇到的情况
dnf update --security 悄无声息地以“无事可做”结束。 仓库中没有安全公告(updateinfo)元数据时就会出现这种情况。createrepo_c 只能从 rpm 文件生成 primary、filelists 和 other,而公告信息并不存在于 rpm 内部。它不报错、什么也不做,恰恰是危险之处。 应养成使用 dnf updateinfo --summary 进行确认的习惯。
下一个实验要做什么
使用 dnf 检查仓库、安装软件包,通过 provides 反向追踪来源,再利用历史记录回滚并锁定版本。