dnf 命令详解与参数实测(Fedora 44)
在 Fedora 44(dnf5 5.4.3.0)上逐项实测 dnf 的安装卸载升级降级、查询反查、软件组、历史回滚、仓库配置与常用全局选项,回显逐字可复现。
dnf 命令详解与参数实测(Fedora 44)
目标:系统掌握 Fedora 上 dnf 的日常包管理操作——元数据缓存、查询与反查、安装/卸载/升级/重装/降级、按包下载、软件组、事务历史与撤销回滚、仓库启用禁用与新增,以及高频全局选项。全文所有命令与回显均在 Fedora 44(dnf5 5.4.3.0,x86_64)上真实执行并逐字记录,退出码一并给出,可直接照搬复现。
一、环境信息
本章先固化实测环境,后文所有回显都基于该环境。验证手段:cat /etc/os-release 与 dnf --version 两条命令即可复验版本,任何人照做都应得到一致结果。
$ grep -E '^(NAME|ID|VERSION_ID|SUPPORT_END)=' /etc/os-release
NAME="Fedora Linux"
ID=fedora
VERSION_ID=44
SUPPORT_END=2027-05-19
| 项目 | 实测值 |
|---|---|
| 发行版 | Fedora Linux 44(官方支持期至 2027-05-19) |
| 架构 | x86_64 |
| dnf 实现 | dnf5(/usr/bin/dnf 是指向 dnf5 的符号链接) |
| dnf5 版本 | 5.4.3.0(软件包 dnf5-5.4.3.0-2.fc44) |
| libdnf5 | 5.4.3.0(软件包 libdnf5-5.4.3.0-2.fc44) |
| RPM | 6.0.2-1.fc44 |
| 基线已装包数 | 147(rpm -qa | wc -l) |
| 默认启用仓库 | fedora、fedora-cisco-openh264、updates |
$ dnf --version
dnf5 version 5.4.3.0
dnf5 plugin API version 2.0
libdnf5 version 5.4.3.0
libdnf5 plugin API version 2.2
Loaded dnf5 plugins:
name: builddep
version: 1.0.0
API version: 2.0
name: changelog
version: 1.0.0
API version: 2.0
name: config-manager
version: 0.1.0
API version: 2.0
name: copr
version: 0.1.0
API version: 2.0
name: needs_restarting
version: 1.0.0
API version: 2.0
name: repoclosure
version: 1.0.0
API version: 2.0
name: repomanage
version: 1.0.0
API version: 2.0
name: reposync
version: 1.0.0
API version: 2.0
命令本体与配置文件:
$ ls -l /usr/bin/dnf
lrwxrwxrwx 1 root root 4 Aug 19 00:00 /usr/bin/dnf -> dnf5
$ cat /etc/dnf/dnf.conf
# see `man dnf.conf` for defaults and possible options
[main]
tsflags=nodocs
对上表与回显的解读:
- Fedora 41 起,
dnf命令由新一代实现 dnf5 承担,dnf --version直接输出dnf5 version,rpm -qf /usr/bin/dnf返回dnf5-5.4.3.0-2.fc44,说明"dnf"这个名字在 Fedora 44 上就是 dnf5。 tsflags=nodocs是 Fedora 官方最小化镜像的默认配置:安装软件包时不带 man 手册和 texinfo 文档。后文回显里Download size、Installed size都是在该配置下测得的,数值会比桌面版安装略小,属于正常现象。Loaded dnf5 plugins列出的 builddep、changelog、config-manager、copr 等是随主包附带的官方插件,它们各自贡献若干子命令(如dnf config-manager、dnf changelog),后文都会实测到。
💡 dnf5、dnf4、yum、apt 是什么关系:yum 是 RHEL/CentOS 57 时代的 Python 实现,进入 EOL;dnf4 是 Fedora 2240 与 RHEL 8/9 的默认实现(Python + libdnf/librepo,依赖解析用 libsolv);dnf5 是 C++ 重写版(libdnf5),命令行行为大体兼容但有明确差异,Fedora 41 起成为默认,RHEL 10 同样采用。apt 是 Debian/Ubuntu 体系的包管理器,与 RPM 系无直接血缘。本文实测中撞到的典型差异包括:config-manager --set-enabled 在 dnf5 已移除(改为 config-manager enable 子命令)、dnf help 子命令不存在、history 新增 store/replay、config-manager setopt 的持久化落在 /etc/dnf/repos.override.d/ 覆盖层而不是直接改 .repo 文件——这些都会在对应小节用实测回显展开。依赖解析器方面:yum3 早期是自研求解器,dnf4 与 dnf5 都基于 SAT 求解器 libsolv,apt 则是自家的 APT 求解器,因此"同一组包在 dnf 与 apt 下解出的安装集合不同"是正常现象。本文全部实测基于 dnf5。
二、命令概览(--help 全量回显 + 测试数据准备)
不翻手册时,dnf --help 是最快的入口。dnf5 没有 dnf help 子命令(实测见 3.13 与 FAQ),所以看子命令帮助一律用 dnf <子命令> --help。本章给出 dnf --help 的全量回显并逐块解读,然后准备全文共用的测试数据。
2.1 dnf --help 全量回显
$ dnf --help
Usage:
dnf5 [GLOBAL OPTIONS] <COMMAND> ...
Description:
DNF5 is a program for maintaining packages.
Software Management Commands:
do Do transaction
install Install software
upgrade Upgrade software
remove Remove (uninstall) software
distro-sync Upgrade or downgrade installed software to the latest available versions
downgrade Downgrade software
reinstall Reinstall software
debuginfo-install Install debuginfo packages.
swap Remove software and install another in one transaction
mark Change the reason of an installed package
autoremove Remove all unneeded packages originally installed as dependencies.
provides Find what package provides the given value
replay Replay a transaction that was previously stored to a directory
check-upgrade Check for available package upgrades
check Check for problems in the packagedb
Query Commands:
leaves List groups of installed packages not required by other installed packages
repoquery Search for packages matching various criteria
search Search for software matching all specified strings
list Lists packages depending on the packages' relation to the system
info Lists packages depending on the packages' relation to the system with additional details
Subcommands:
group Manage comps groups
environment Manage comps environments
module Manage modules
history Manage transaction history
repo Manage repositories
advisory Manage advisories
versionlock Manage versionlock configuration
system-upgrade Prepare system for upgrade to a new release
offline-distrosync Store a distro-sync transaction to be performed offline
offline-upgrade Store an upgrade transaction to be performed offline
offline Manage offline transactions
config-manager Manage configuration
Compatibility Aliases:
check-update Alias for 'check-upgrade'
dg Alias for 'downgrade'
dsync Alias for 'distro-sync'
grp Alias for 'group'
if Alias for 'info'
in Alias for 'install'
ls Alias for 'list'
mc Alias for 'makecache'
rei Alias for 'reinstall'
repoinfo Alias for 'repo info'
repolist Alias for 'repo list'
rm Alias for 'remove'
rq Alias for 'repoquery'
se Alias for 'search'
up Alias for 'upgrade'
update Alias for 'upgrade'
updateinfo Alias for 'advisory'
upgrade-minimal Alias for 'upgrade --minimal'
Commands:
clean Remove or expire cached data
download Download software to the current directory
makecache Generate the metadata cache
builddep Install build dependencies for package or spec file
changelog Show package changelogs
copr Manage Copr repositories (add-ons provided by users/community/third-party)
needs-restarting Determine whether system or systemd services need restarting
repoclosure Print list of unresolved dependencies for repositories
repomanage Manage a directory with repodata or with rpm packages
reposync Synchronize a remote DNF repository to a local directory.
build-dep Compatibility alias for 'builddep'
Global options:
-h, --help Print help
--config=CONFIG_FILE_PATH Configuration file location
-q, --quiet In combination with a non-interactive command, shows just the relevant content. Suppresses messages notifying about the current state or actions of dnf5.
-C, --cacheonly Run entirely from system cache, don't update the cache and use it even in case it is expired.
--color=COLOR Control whether color is used.
--refresh Force refreshing metadata before running the command.
--repofrompath=REPO_ID,REPO_PATH create additional repository using id and path
--setopt=[REPO_ID.]OPTION=VALUE set arbitrary config and repo options
--setvar=VAR_NAME=VALUE set arbitrary variable
-y, --assumeyes automatically answer yes for all questions
--assumeno automatically answer no for all questions
--best try the best available package versions in transactions
--no-best do not limit the transaction to the best candidate
--allow-vendor-change allow automatic package replacements from different vendors
--no-allow-vendor-change do not allow automatic package replacements from different vendors
--no-docs Don't install files that are marked as documentation (which includes man pages and texinfo documents)
-x package,..., --exclude=package,... exclude packages by name or glob
--enable-repo=REPO_ID,... Enable additional repositories. List option. Supports globs, can be specified multiple times.
--disable-repo=REPO_ID,... Disable repositories. List option. Supports globs, can be specified multiple times.
--repo=REPO_ID,... Enable just specific repositories. List option. Supports globs, can be specified multiple times.
--no-gpgchecks disable OpenPGP signature checking (if RPM policy allows)
--no-plugins Disable all libdnf5 plugins
--enable-plugin=PLUGIN_NAME,... Enable libdnf5 plugins by name. List option. Supports globs, can be specified multiple times.
--disable-plugin=PLUGIN_NAME,... Disable libdnf5 plugins by name. List option. Supports globs, can be specified multiple times.
--comment=COMMENT add a comment to transaction
--installroot=ABSOLUTE_PATH set install root
--use-host-config use configuration, reposdir, and vars from the host system rather than the installroot
--releasever=RELEASEVER override the value of $releasever in config and repo files
--releasever-major=RELEASEVER_MAJOR override the value of $releasever_major in config and repo files
--releasever-minor=RELEASEVER_MINOR override the value of $releasever_minor in config and repo files
--show-new-leaves Show newly installed leaf packages and packages that became leaves after a transaction.
--debugsolver Dump detailed solving results into files
--dump-main-config Print main configuration values to stdout
--dump-repo-config=REPO_ID,... Print repository configuration values to stdout. List option. Supports globs
--dump-variables Print variable values to stdout
--version Show DNF5 version and exit
--forcearch=FORCEARCH Force the use of a different architecture.
--skip-file-locks Skip acquiring file locks, such as the lock on the system repository
Options Compatibility aliases:
-c CONFIG_FILE_PATH Alias for '--config'
--nobest Alias for '--no-best'
--nodocs Alias for '--no-docs'
--enablerepo=REPO_ID,... Alias for '--enable-repo'
--disablerepo=REPO_ID,... Alias for '--disable-repo'
--repoid=REPO_ID,... Alias for '--repo'
--nogpgcheck Alias for '--no-gpgchecks'
--noplugins Alias for '--no-plugins'
--enableplugin=PLUGIN_NAME,... Alias for '--enable-plugin'
--disableplugin=PLUGIN_NAME,... Alias for '--disable-plugin'
2.2 回显解读
命令分组。dnf5 把子命令分为五类:Software Management Commands 是会真实改动系统的事务类命令(install/upgrade/remove/downgrade/reinstall/autoremove/swap/distro-sync…);Query Commands 是只读查询(search/info/list/provides/repoquery/leaves);Subcommands 是需要再跟一层子命令的入口(group/history/repo/config-manager…);Commands 是独立工具型命令(clean/makecache/download/changelog…);Compatibility Aliases 是短别名表。日常运维最高频的三十来个命令全部覆盖在本文第三章。
别名表值得专门一读:in=install、up=upgrade、rm=remove、se=search、ls=list、if=info、mc=makecache、rq=repoquery、rei=reinstall、dg=downgrade、dsync=distro-sync、grp=group。另有两条语义级别名:check-update 实际是 check-upgrade(后者才是本名),update 实际是 upgrade——这就是为什么老脚本里 dnf update 和 dnf upgrade 等价。repoinfo/repolist 则是 repo info/repo list 的扁平别名。
全局选项Compat表。末尾的 Options Compatibility aliases 是 dnf4 风格选项到 dnf5 风格的映射:--enablerepo/--disablerepo 对应新写法 --enable-repo/--disable-repo,--nogpgcheck 对应 --no-gpgchecks。老脚本不用改也能跑,但写新脚本建议统一用 dnf5 原生拼写。
💡 子命令帮助的两种姿势:dnf4 时代 dnf help install 与 dnf install --help 都能看帮助;dnf5 只保留了后者,dnf help install 会报 Unknown argument "help" for command "dnf5"(实测退出码 2,见 3.13)。排查子命令报错时先确认你查的是 dnf5 帮助文档(man dnf5),别拿 dnf4 的 man dnf 对照。
2.3 测试数据准备
全文演示围绕以下对象展开,先建工作目录:
mkdir -p /root/demo/dnf && cd /root/demo/dnf
| 演示对象 | 用途 | 特点 |
|---|---|---|
| tree | 单文件小工具,装/卸/重装/降级演示 | 几乎无依赖,回显干净 |
| cowsay | 依赖解析演示 | 连带拉起 60 余个 Perl 依赖,最能看出事务结构 |
| figlet、sl | 历史撤销演示 | 两个互相独立的小包,方便逐条 undo |
| fonts 软件组 | 隐藏组与组安装演示 | Uservisible: no,安装后不显示在默认组列表 |
| createrepo_c | 自建本地仓库 | 生成 repodata 元数据 |
验证手段约定:每个事务命令执行后用 rpm -q <包名> 或 dnf list --installed <包名> 复核,关键命令补记 $? 退出码;凡涉及网络下载的回显,速率与已用时间是当时网络状况的真实记录,复现时数值不同属正常,文本内容应当一致。
三、参数逐项实测
本章按"缓存 → 查询 → 反查 → 安装卸载 → 升级降级重装 → 下载 → 软件组 → 历史 → 仓库配置 → 全局选项"的顺序逐项实测。每个参数给出:引导说明、实测命令、逐字回显、行为解读。所有命令以 root 身份在系统默认源下执行。
3.1 makecache:生成元数据缓存
makecache 把各仓库的 repodata(主索引、文件清单、其他信息三类 XML,dnf5 下为 zstd 压缩)下载到本地 /var/cache/libdnf5/,后续查询与事务都读缓存,避免每次联网。Fedora 各仓库的 metadata_expire 不同(fedora 7 天、updates 6 小时),所以 makecache 是否真的下载取决于缓存是否过期——实测正好能看到两种情况。
$ dnf makecache
Updating and loading repositories:
Fedora 44 - x86_64 - Updates 100% | 18.9 KiB/s | 8.2 KiB | 00m00s
Repositories loaded.
Metadata cache created.
$ echo $?
0
这次只有 updates 重新下载(8.2 KiB,仓库索引增量),因为 fedora(7 天有效)和 openh264(14 天有效)的元数据仍在有效期内。紧接着再跑一次:
$ dnf makecache
Updating and loading repositories:
Repositories loaded.
Metadata cache created.
$ echo $?
0
全部命中缓存,直接进入 Repositories loaded。清空后重建可以看到全量下载:
$ dnf clean all
Removed 27 files, 17 directories (total of 263 MiB). 0 errors occurred.
$ dnf makecache
Updating and loading repositories:
Fedora 44 - x86_64 - Updates 100% | 4.1 MiB/s | 12.0 MiB | 00m03s
Fedora 44 openh264 (From Cisco) - x86_ 100% | 2.4 KiB/s | 5.3 KiB | 00m02s
Fedora 44 - x86_64 100% | 4.6 MiB/s | 36.4 MiB | 00m08s
Repositories loaded.
Metadata cache created.
$ du -sh /var/cache/libdnf5
105M /var/cache/libdnf5
强制刷新(无视 metadata_expire):
$ dnf makecache --refresh
Updating and loading repositories:
Fedora 44 - x86_64 - Updates 100% | 2.3 MiB/s | 11.8 MiB | 00m05s
Fedora 44 openh264 (From Cisco) - x86_ 100% | 1.3 KiB/s | 5.3 KiB | 00m04s
Fedora 44 - x86_64 100% | 7.6 MiB/s | 36.5 MiB | 00m05s
Metadata cache created.
Repositories loaded.
解读:Fedora 44 全量元数据约 48 MiB(下载体积),解压落盘后缓存目录 105 MiB;makecache 默认按过期时间增量工作,--refresh 才无条件重下。系统自带的定时任务每天会自动跑一次等效操作,手工 makecache 主要用于:刚改完 repo 配置、刚挂载新源、或脚本里要保证元数据新鲜。
💡 缓存目录为什么叫 libdnf5:dnf4 时代缓存在 /var/cache/dnf/,dnf5 换到 /var/cache/libdnf5/,每个仓库一个 <repoid>-<哈希> 子目录。遇到"换个源就旧缓存作祟"的灵异问题时,rm -rf /var/cache/libdnf5(或 dnf clean all)后再 makecache 是标准复位手段。
3.2 clean:清除缓存
clean 按"缓存类型"删除数据,先看它支持哪些类型:
$ dnf clean --help
Usage:
dnf5 [GLOBAL OPTIONS] clean [ARGUMENTS]
Arguments:
cache_types List of cache types to clean up. Supported types: all, packages, metadata, dbcache, expire-cache
逐类实测(每步后查看缓存目录体积):
$ du -sh /var/cache/libdnf5
105M /var/cache/libdnf5
$ dnf clean packages
Removed 0 files, 0 directories (total of 0 B). 0 errors occurred.
$ du -sh /var/cache/libdnf5
105M /var/cache/libdnf5
$ dnf clean metadata
Removed 18 files, 6 directories (total of 104 MiB). 0 errors occurred.
$ du -sh /var/cache/libdnf5
16K /var/cache/libdnf5
$ dnf clean dbcache
Removed 0 files, 0 directories (total of 0 B). 0 errors occurred.
$ dnf clean all
Removed 0 files, 0 directories (total of 0 B). 0 errors occurred.
解读:dnf5 的缓存主要是"元数据"(repo索引)与"下载的 rpm 包"两大块。上面 clean packages 清出 0 B,是因为此前的演示包已被清理;clean metadata 一把清掉 104 MiB。dnf clean packages 在 dnf5 里不会清掉 makecache 下载的元数据,clean metadata 也不会动已下载的 rpm,两者分开维护;一线运维最常用的还是 clean all。另一个差别:expire-cache 类型只是把元数据标记为过期(下次使用时重新下载),不是删除文件。
💡 dnf4 → dnf5 的 clean 差异:dnf4 支持 dbcache/keys/dbx/metadata/pkgs/all 等更多子类型;dnf5 精简为 all/packages/metadata/dbcache/expire-cache 五种。跨版本写通用脚本时,只依赖 clean all 最安全。
3.3 repolist / repo:查看仓库
repolist 是 repo list 的别名。默认只显示启用的仓库,且 dnf5 的输出只有两列:
$ dnf repolist
repo id repo name
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
updates Fedora 44 - x86_64 - Updates
加 --all 看全部(含禁用仓库,多一列 status):
$ dnf repolist --all
repo id repo name status
fedora Fedora 44 - x86_64 enabled
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64 enabled
fedora-cisco-openh264-debuginfo Fedora 44 openh264 (From Cisco) - x86_64 - Debug disabled
fedora-cisco-openh264-source Fedora 44 openh264 (From Cisco) - x86_64 - Source disabled
fedora-debuginfo Fedora 44 - x86_64 - Debug disabled
fedora-source Fedora 44 - Source disabled
updates Fedora 44 - x86_64 - Updates enabled
updates-debuginfo Fedora 44 - x86_64 - Updates - Debug disabled
updates-source Fedora 44 - Updates Source disabled
updates-testing Fedora 44 - x86_64 - Test Updates disabled
updates-testing-debuginfo Fedora 44 - Test Updates Debug disabled
updates-testing-source Fedora 44 - Test Updates Source disabled
单个仓库的详情用 repo info(repoinfo 是其别名,dnf repoinfo 无参可列全部启用仓库):
$ dnf repo info fedora
Updating and loading repositories:
Repositories loaded.
Repo ID : fedora
Name : Fedora 44 - x86_64
Status : enabled
Priority : 99
Cost : 1000
Type : available
Metadata expire : 604800 seconds (last: 2026-10-17 00:18:46)
Skip if unavailable : false
Config file : /etc/yum.repos.d/fedora.repo
URLs :
Base URL : https://mirrors.qlu.edu.cn/fedora/releases/44/Everything/x86_64/os/ (35 more)
Metalink : https://mirrors.fedoraproject.org/metalink?repo=fedora-44&arch=x86_64
解读三点:一是 Base URL 后的 35 more,说明 metalink 机制下 dnf 实际缓存了 36 个镜像候选,当前会话选中的这个是测速结果,你的机器上看到的第一条 URL 大概率不同,这是镜像调度而非配置错误;二是 Metadata expire: 604800 seconds 即 7 天,与 /etc/yum.repos.d/fedora.repo 里 metadata_expire=7d 一致;三是调试源与源码仓库(-debuginfo/-source)默认全部禁用,dnf config-manager enable 可按需打开(见 3.19)。
💡 metalink 与 baseurl:.repo 文件里 metalink= 指向镜像列表服务,dnf 启动时向它请求候选镜像并测速选优;baseurl= 则写死地址(Fedora 官方 repo 里被注释掉了)。内网机器推荐自建镜像后用 baseurl 直连,公网机器保持 metalink 即可。
3.4 search:按关键词搜包
search 在包名与 summary(一句话简介)里做关键词匹配:
$ dnf search cowsay
Updating and loading repositories:
Repositories loaded.
Matched fields: name (exact)
cowsay.noarch Configurable speaking/thinking cow
Matched fields: name, summary
cowsay-beefymiracle.noarch Cowsay file for the Beefy Miracle
Matched fields: name
xcowsay.x86_64 Displays a cute cow and message on your desktop
多结果场景(截取前 15 行):
$ dnf search tree | sed -n '1,15p'
Updating and loading repositories:
Repositories loaded.
Matched fields: name (exact), summary
tree.x86_64 File system tree viewer
Matched fields: name, summary
NearTree-devel.i686 Development tools for compiling programs using NearTree
NearTree-devel.x86_64 Development tools for compiling programs using NearTree
cockpit-ostree.noarch Cockpit user interface for rpm-ostree
ebtree.i686 Elastic binary tree library
ebtree.x86_64 Elastic binary tree library
ebtree-devel.i686 Development files for ebtree
ebtree-devel.x86_64 Development files for ebtree
erlang-mqtree.x86_64 Index tree for MQTT topic filters
fedora-release-ostree-desktop.noarch Configuration package for rpm-ostree variants to add rpm-ostree polkit rules
fedora-repos-ostree.noarch OSTree specific files
flexmark-java-tree-iteration.noarch Flexmark library for recursive tree iteration
geany-plugins-treebrowser.x86_64 Alternate file browser plugin providing a tree view of directories
搜不到时退出码是 0:
$ dnf search zzzznotexist
Updating and loading repositories:
Repositories loaded.
No matches found.
$ echo $?
0
解读:输出按 Matched fields 分组——name (exact) 精确同名排最前,其次 name, summary 双命中,再往后是仅 summary 命中。search 只查"名字+简介"两个字段,想按文件、依赖关系找包要用 provides/repoquery(见 3.7、3.8)。写脚本时注意:search 无结果返回 0,不能用 $? 判断命中与否,要 grep 输出内容。
3.5 info:查看包详情
$ dnf info cowsay
Updating and loading repositories:
Repositories loaded.
Available packages
Name : cowsay
Epoch : 0
Version : 3.8.4
Release : 5.fc44
Architecture : noarch
Download size : 54.5 KiB
Installed size : 80.5 KiB
Source : cowsay-3.8.4-5.fc44.src.rpm
Repository : fedora
Summary : Configurable speaking/thinking cow
URL : https://github.com/cowsay-org/cowsay
License : GPL-2.0-or-later
Description : cowsay is a configurable talking cow, written in Perl. It operates
: much as the figlet program does, and it is written in the same spirit
: of silliness.
: It generates ASCII pictures of a cow with a message. It can also generate
: pictures of other animals.
Vendor : Fedora Project
已安装的包会出现在 Installed packages 小节。查不存在的包退出码为 1:
$ dnf info nosuchpkg-404
Updating and loading repositories:
Repositories loaded.
No matching packages to list
$ echo $?
1
解读:Epoch: 0 表示无纪元;Repository: fedora 说明该版本来自发行版仓库而非 updates——cowsay 自 Fedora 44 首发后没有推送过更新。Available packages/Installed packages 的小节标题是区分安装状态的第一视觉线索;dnf info 同时给出 Download size 与 Installed size,估算磁盘占用比 list 方便。
💡 N-E-V-RA 命名法:RPM 包的完整标识是 Name-Epoch:Version-Release.Arch,如 cowsay-0:3.8.4-5.fc44.noarch。Version 是上游版本号(3.8.4),Release 是 Fedora 打包者的修订号(5.fc44,含目标发行版标记 .fc44)。读回显、写 repoquery 查询格式串、对比版本先后时都用得上这套记法。
3.6 list:按安装状态列包
list 按四种关系筛包,实测全部形态:
$ dnf list --installed | sed -n '1,12p'
Installed packages
alternatives.x86_64 1.33-5.fc44 97840e1176ff4d8b98a420e1faba3487
audit-libs.x86_64 4.2.1-1.fc44 0eae96ab45874228a86a12a132e699ed
authselect.x86_64 1.7.1-1.fc44 97840e1176ff4d8b98a420e1faba3487
authselect-libs.x86_64 1.7.1-1.fc44 97840e1176ff4d8b98a420e1faba3487
bash.x86_64 5.3.9-3.fc44 97840e1176ff4d8b98a420e1faba3487
bzip2.x86_64 1.0.8-23.fc44 97840e1176ff4d8b98a420e1faba3487
bzip2-libs.x86_64 1.0.8-23.fc44 97840e1176ff4d8b98a420e1faba3487
ca-certificates.noarch 2025.2.80_v9.0.304-7.fc44 0eae96ab45874228a86a12a132e699ed
coreutils.x86_64 9.10-5.fc44 0eae96ab45874228a86a12a132e699ed
coreutils-common.x86_64 9.10-5.fc44 0eae96ab45874228a86a12a132e699ed
cracklib.x86_64 2.10.3-1.fc44 0eae96ab45874228a86a12a132e699ed
$ dnf list --installed | wc -l
147
$ dnf list --available cowsay
Updating and loading repositories:
Repositories loaded.
Available packages
cowsay.noarch 3.8.4-5.fc44 fedora
$ dnf list --upgrades | sed -n '1,12p'
Updating and loading repositories:
Repositories loaded.
Available upgrades
ca-certificates.noarch 2026.2.90_v9.0.317-1.fc44 updates
curl.x86_64 8.18.0-14.fc44 updates
dnf5.x86_64 5.4.6.0-1.fc44 updates
dnf5-plugins.x86_64 5.4.6.0-1.fc44 updates
elfutils-default-yama-scope.noarch 0.196-1.fc44 updates
elfutils-libelf.x86_64 0.196-1.fc44 updates
elfutils-libs.x86_64 0.196-1.fc44 updates
fedora-gpg-keys.noarch 44-2 updates
fedora-repos.noarch 44-2 updates
glib2.x86_64 2.88.4-1.fc44 updates
glibc.x86_64 2.43-9.fc44 updates
$ dnf list --obsoletes
Updating and loading repositories:
Repositories loaded.
最后两列的含义:--installed 行尾的长十六进制串是该包安装时来源仓库的 repodata 校验和(同批安装的包共享同一串,如 97840e1176ff4d8b98a420e1faba3487 是装机时刻的 fedora 仓库),--available/--upgrades 行尾是仓库名。--installed 共 147 行 = 1 行标题 + 146 个包,比 rpm -qa 少的正是 gpg-pubkey 密钥包——dnf list 不展示它。
--showduplicates 显示仓库里保留的多个历史版本:
$ dnf list --showduplicates cowsay
Updating and loading repositories:
Repositories loaded.
Available packages
cowsay.noarch 3.8.4-5.fc44 fedora
此处只列出一个版本,因为 Fedora 官方源只保留最新版;自建镜像若用 repomanage 保留多版本,这里就能看到全部(官方源的内核 installonly 包则天然多版本共存)。
⚠️ 一个从 dnf4 带来的书写陷阱,实测如下——不带 -- 时 installed 会被当成包名通配模式:
$ dnf list installed tree
Updating and loading repositories:
Repositories loaded.
Available packages
tree.x86_64 2.2.1-4.fc44 fedora
$ dnf list installed
Updating and loading repositories:
Repositories loaded.
No matching packages to list
$ echo $?
1
第二条命令报 No matching packages to list 退出码 1——它把 installed 当成了名为 installed 的包。所以要么全程 --installed,要么 dnf list installed 后必须跟包名。
3.7 provides:反查"谁提供这个文件/能力"
最常见用法:只知道命令路径,不知道属于哪个包。
$ dnf provides /usr/bin/cowsay
Updating and loading repositories:
Fedora 44 - x86_64 - Updates 100% | 8.5 MiB/s | 26.8 MiB | 00m03s
Fedora 44 openh264 (From Cisco) - x86_ 100% | 2.8 KiB/s | 7.3 KiB | 00m03s
Fedora 44 - x86_64 100% | 10.5 MiB/s | 56.6 MiB | 00m05s
Repositories loaded.
cowsay-3.8.4-5.fc44.noarch : Configurable speaking/thinking cow
Repo : fedora
Matched From :
Filename : /usr/bin/cowsay
也能按"能力名"(provide 字段)查:
$ dnf provides cowsay
Updating and loading repositories:
Repositories loaded.
cowsay-3.8.4-5.fc44.noarch : Configurable speaking/thinking cow
Repo : fedora
Matched From :
Provide : cowsay = 3.8.4-5.fc44
查不存在的提供项时,dnf5 会给出一行很实用的提示:
$ dnf provides 'perl(Cowsay)'
Updating and loading repositories:
Repositories loaded.
No matches found. If searching for a file, try specifying the full path or using a wildcard prefix ("*/") at the beginning.
解读:provides 匹配三个层面——文件路径、RPM Provide 能力(含 perl(Cowsay) 这类虚拟依赖)、以及包名本身。回显里 Matched From 之下区分 Filename 还是 Provide,一眼可见命中类型。这次查询还顺带触发了元数据重新下载(前 4 行进度条),因为文件清单(filelists)元数据默认不常驻,首次 provides 会按需拉取。
3.8 repoquery:结构化查询的瑞士军刀
repoquery 是 dnf5 查询体系里功能最全的命令,支持自定义输出格式和依赖方向查询。先看它支持的筛选维度(节选):
$ dnf repoquery --help | sed -n '1,40p'
Usage:
dnf5 [GLOBAL OPTIONS] repoquery [OPTIONS] [ARGUMENTS]
Formatting:
-i, --info Show detailed information about the packages.
--querytags Display available tags for --queryformat.
--queryformat=QUERYFORMAT Display format for packages. Default is "%{full_nevra}".
--changelogs Display package changelogs.
--files Like --queryformat="%{files}" but deduplicated and sorted.
--sourcerpm Like --queryformat="%{sourcerpm}" but deduplicated and sorted.
--location Like --queryformat="%{location}" but deduplicated and sorted.
--conflicts Like --queryformat="%{conflicts}" but deduplicated and sorted.
--depends Like --queryformat="%{depends}" but deduplicated and sorted.
--enhances Like --queryformat="%{enhances}" but deduplicated and sorted.
--obsoletes Like --queryformat="%{obsoletes}" but deduplicated and sorted.
--provides Like --queryformat="%{provides}" but deduplicated and sorted.
--recommends Like --queryformat="%{recommends}" but deduplicated and sorted.
--requires Like --queryformat="%{requires}" but deduplicated and sorted.
--requires-pre Like --queryformat="%{requires_pre}" but deduplicated and sorted.
--suggests Like --queryformat="%{suggests}" but deduplicated and sorted.
--supplements Like --queryformat="%{supplements}" but deduplicated and sorted.
--qf=QUERYFORMAT Alias for '--queryformat'
-l, --list Alias for '--files'
Options:
--available Query available packages (default).
--installed Query installed packages.
--installed-from-repo=REPO_ID,... Filters installed packages by the ID of the repository they were installed from.
--leaves Limit to groups of installed packages not required by other installed packages.
--userinstalled Limit to packages that are not installed as dependencies or weak dependencies.
--duplicates Limit to installed duplicate packages (i.e. more package versions for the same name and architecture). Installonly packages are excluded from this set.
--unneeded Limit to unneeded installed packages (i.e. packages that were installed as dependencies but are no longer needed).
--installonly Limit to installed installonly packages.
--extras Limit to installed packages that are not present in any available repository.
--upgrades Limit to available packages that provide an upgrade for some already installed package.
--advisories=ADVISORY_NAME,... Include content contained in advisories with specified name. List option.
--advisory-severities=ADVISORY_SEVERITY,... Include content contained in advisories with specified severity. List option. Can be "critical", "important", "moderate", "low", "none".
--bzs=BUGZILLA_ID,... Include content contained in advisories that fix a Bugzilla ID, Eg. 123123. List option.
--cves=CVE_ID,... Include content contained in advisories that fix a CVE (Common Vulnerabilities and Exposures) ID, Eg. CVE-2201-0123. List option.
--security Include content contained in security advisories.
基础查询与自定义格式:
$ dnf repoquery cowsay
Updating and loading repositories:
Repositories loaded.
cowsay-0:3.8.4-5.fc44.noarch
$ dnf repoquery --qf '%{name}-%{version}-%{release}.%{arch} (%{repoid})' cowsay
Updating and loading repositories:
Repositories loaded.
cowsay-3.8.4-5.fc44.noarch (fedora)
列文件清单与依赖(均截取部分):
$ dnf repoquery --list cowsay | sed -n '1,10p'
Updating and loading repositories:
Repositories loaded.
/etc/cowsay
/etc/cowsay/cowpath.d
/usr/bin/animalsay
/usr/bin/cowsay
/usr/bin/cowthink
/usr/share/bash-completion/completions/cowsay
/usr/share/cowsay
/usr/share/cowsay/cows
/usr/share/cowsay/cows/actually.cow
/usr/share/cowsay/cows/alpaca.cow
$ dnf repoquery --requires cowsay | sed -n '1,12p'
Updating and loading repositories:
Repositories loaded.
/usr/bin/perl
/usr/bin/sh
filesystem >= 3.6-1
perl(Cwd)
perl(File::Basename)
perl(File::Find)
perl(Getopt::Std)
perl(Text::Tabs)
perl(Text::Wrap)
perl-Encode
反向依赖:谁依赖 perl-interpreter(前 8 行):
$ dnf repoquery --whatrequires perl-interpreter | sed -n '1,8p'
Updating and loading repositories:
Repositories loaded.
389-ds-base-0:3.2.0-15.fc44.x86_64
389-ds-base-logconv-perl-0:3.2.3-5.fc44.x86_64
BackupPC-0:4.4.0-22.fc44.x86_64
EekBoek-0:2.051-15.fc44.noarch
GMT-common-0:6.6.0-5.fc44.noarch
IP2Location-0:8.7.0-3.fc44.i686
IP2Location-0:8.7.0-3.fc44.x86_64
LaTeXML-0:0.8.8-3.fc42.noarch
解读四点:默认查询对象是仓库里的可用包(--available 是默认值),查本机要显式 --installed;默认输出格式 %{full_nevra}(即 cowsay-0:3.8.4-5.fc44.noarch),--qf/--queryformat 可按 tag 自由拼装(全部可用 tag 用 dnf repoquery --querytags 查看);--whatrequires 只看硬依赖(requires),想含推荐依赖(recommends/supplements)需换 dnf repoquery --whatrecommends 等对应选项;输出按 NEVRA 全列,同一个包的 i686/x86_64 会各占一行,过滤时注意。
💡 provides vs repoquery 怎么选:日常"这文件哪来的"用 provides,一句话出结果;要做自动化处理(脚本消费、按格式拼接、依赖方向分析、安全通告过滤)一律 repoquery——它是 dnf5 里对 rpm 查询能力(rpm -q --qf 那套 tag 语法)在仓库维度的完整移植。
3.9 install:安装
先看 install 自身的选项(与依赖冲突处理相关,后面都会测):
$ dnf install --help
Usage:
dnf5 [GLOBAL OPTIONS] install [OPTIONS] [ARGUMENTS]
Options:
--allowerasing Allow removing of installed packages to resolve problems
--skip-broken Allow resolving of depsolve problems by skipping packages
--skip-unavailable Allow skipping unavailable packages
--allow-downgrade Allow downgrade of dependencies for resolve of requested operation
--no-allow-downgrade Disable downgrade of dependencies for resolve of requested operation
--from-repo=REPO_ID,... The following items can be selected only from the specified repositories. All enabled repositories will still be used to satisfy dependencies.
--from-vendor=VENDOR,... The following items can be selected only from the specified vendors. The vendor is ignored or vendor change policies (if allow_vendor_change=0) will still be used for items that satisfy dependencies.
--downloadonly Only download packages for a transaction
--offline Store the transaction to be performed offline
--advisories=ADVISORY_NAME,... Include content contained in advisories with specified name. List option.
--advisory-severities=ADVISORY_SEVERITY,... Include content contained in advisories with specified severity. List option. Can be "critical", "important", "moderate", "low", "none".
--bzs=BUGZILLA_ID,... Include content contained in advisories that fix a Bugzilla ID, Eg. 123123. List option.
--cves=CVE_ID,... Include content contained in advisories that fix a CVE (Common Vulnerabilities and Exposures) ID, Eg. CVE-2201-0123. List option.
--security Include content contained in security advisories.
--bugfix Include content contained in bugfix advisories.
--enhancement Include content contained in enhancement advisories.
--newpackage Include content contained in newpackage advisories.
--store=STORED_TRANSACTION_PATH Store the current transaction in a directory at the specified path instead of running it.
--transient Set up a transient overlay on /usr that will be discarded on reboot.
--advisory=ADVISORY_NAME,... Alias for '--advisories'
--bz=BUGZILLA_ID,... Alias for '--bzs'
--cve=CVE_ID,... Alias for '--cves'
Arguments:
specs List of <package-spec-NPFB>|@<group-spec>|@<environment-spec> to install
单包安装(-y 自动确认):
$ dnf install -y tree
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Installing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
[1/1] tree-0:2.2.1-4.fc44.x86_64 100% | 142.7 KiB/s | 62.7 KiB | 00m00s
--------------------------------------------------------------------------------
[1/1] Total 100% | 43.1 KiB/s | 62.7 KiB | 00m01s
Running transaction
[1/3] Verify package files 100% | 0.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 55.0 B/s | 1.0 B | 00m00s
[3/3] Installing tree-0:2.2.1-4.fc44.x8 100% | 89.7 KiB/s | 121.4 KiB | 00m01s
Complete!
$ echo $?
0
复核:
$ dnf list --installed tree
Installed packages
tree.x86_64 2.2.1-4.fc44 fedora
$ tree --version
tree v2.2.1 (c) 1996 - 2024 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro
连带依赖的全量事务(cowsay,依赖清单截取头尾):
$ dnf install -y cowsay
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Installing:
cowsay noarch 0:3.8.4-5.fc44 fedora 80.5 KiB
Installing dependencies:
groff-base x86_64 0:1.23.0-12.fc44 fedora 3.9 MiB
ncurses x86_64 0:6.6-1.fc44 fedora 611.4 KiB
perl-AutoLoader noarch 0:5.74-525.fc44 updates 20.6 KiB
perl-B x86_64 0:1.89-525.fc44 updates 501.2 KiB
perl-Carp noarch 0:1.54-521.fc44 fedora 46.6 KiB
perl-Class-Struct noarch 0:0.68-525.fc44 updates 25.4 KiB
perl-Data-Dumper x86_64 0:2.192-523.fc44 updates 115.5 KiB
……(中间略)……
perl-vars noarch 0:1.05-525.fc44 updates 3.9 KiB
Installing weak dependencies:
perl-NDBM_File x86_64 0:1.18-525.fc44 updates 28.4 KiB
Transaction Summary:
Installing: 64 packages
Total size of inbound packages is 8 MiB. Need to download 8 MiB.
After this operation, 28 MiB extra will be used (install 28 MiB, remove 0 B).
[ 1/64] perl-Text-Tabs+Wrap-0:2024.001- 100% | 179.8 KiB/s | 21.8 KiB | 00m00s
[ 2/64] cowsay-0:3.8.4-5.fc44.noarch 100% | 363.4 KiB/s | 54.5 KiB | 00m00s
……(中间略)……
[64/64] perl-NDBM_File-0:1.18-525.fc44. 100% | 606.3 KiB/s | 21.8 KiB | 00m00s
--------------------------------------------------------------------------------
[64/64] Total 100% | 2.5 MiB/s | 8.5 MiB | 00m03s
Running transaction
[ 1/66] Verify package files 100% | 2.6 KiB/s | 64.0 B | 00m00s
[ 2/66] Prepare transaction 100% | 3.0 KiB/s | 64.0 B | 00m00s
[ 3/66] Installing ncurses-0:6.6-1.fc44 100% | 21.6 MiB/s | 618.0 KiB | 00m00s
……(中间略)……
[65/66] Installing cowsay-0:3.8.4-5.fc4 100% | 6.7 MiB/s | 89.6 KiB | 00m00s
[66/66] Installing perl-NDBM_File-0:1.1 100% | 117.5 KiB/s | 29.5 KiB | 00m00s
Complete!
$ echo 'dnf5 on Fedora 44' | cowsay
___________________
< dnf5 on Fedora 44 >
-------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
解读:事务清单分三档——Installing(你点名的)、Installing dependencies(硬依赖,SAT 求解器补齐的)、Installing weak dependencies(弱依赖,默认装但可被 --setopt=install_weak_deps=False 关掉,实测见 3.20)。回显里 Installing: 64 packages 对应下载进度 64 项、rpm 层事务 66 步(多出的 2 步是 Verify package files 与 Prepare transaction),三个计数差值是正常结构,不是漏装。
💡 事务(transaction)是 dnf 的最小执行单位:不管你一条命令塞多少包,dnf 先把"要装的、要删的、要升的"整体求解成一个事务,预演给你看(Transaction Summary),确认后按依赖序一次性落库,中途任何一步失败整体回滚到事务前状态。这与 apt"逐个包顺序配置"的粒度不同,也是后面 history undo 能一键撤销整条命令的原因。
3.10 remove:卸载
先用 --assumeno 预演,不真删:
$ dnf remove --assumeno tree
Package Arch Version Repository Size
Removing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Removing: 1 package
After this operation, 120 KiB will be freed (install 0 B, remove 120 KiB).
Operation aborted by the user.
$ echo $?
1
确认无误后真实卸载:
$ dnf remove -y tree
Package Arch Version Repository Size
Removing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Removing: 1 package
After this operation, 120 KiB will be freed (install 0 B, remove 120 KiB).
Running transaction
[1/2] Prepare transaction 100% | 62.0 B/s | 1.0 B | 00m00s
[2/2] Removing tree-0:2.2.1-4.fc44.x86_ 100% | 281.0 B/s | 9.0 B | 00m00s
Complete!
$ dnf list --installed tree
No matching packages to list
$ echo $?
1
解读:--assumeno 让所有交互询问自动回答 no,事务在确认环节被 Operation aborted by the user. 拦下、退出码 1,是安全的"试跑"。remove 只删你点名的包;随它装进来的依赖是否一起清,由 clean_requirements_on_remove(本机默认 1)与显式 --no-autoremove 控制,见下节与 3.11。
💡 remove 的输出顺序是 stderr/stdout 交缠:仔细看 --assumeno 那段,After this operation, 120 KiB will be freed (install 0 B, remove 120 KiB). 出现在包表格之前,与 -y 版本相反——dnf5 把事务摘要写 stdout、进度与提示写 stderr,管道/重定向采集日志时顺序会错乱,需要原始顺序请 2>&1 合并后再看(排障实录见 FAQ)。
3.11 autoremove:清理孤儿依赖
autoremove 删除"当初作为依赖装上、现在已无人需要"的包。dnf4 时代删除包会顺手清依赖(clean_requirements_on_remove=1),但凡是你用 remove 时带过 --no-autoremove、或历史原因留下的孤儿,都得靠 autoremove 收尾。先用 cowsay 构造现场:上一节我们用 --no-autoremove 卸载 cowsay,把 61 个 Perl 依赖留在系统里:
$ dnf remove -y --no-autoremove cowsay
After this operation, 80 KiB will be freed (install 0 B, remove 80 KiB).
Running transaction
Package Arch Version Repository Size
Removing:
cowsay noarch 0:3.8.4-5.fc44 fedora 80.5 KiB
Transaction Summary:
Removing: 1 package
[1/2] Prepare transaction 100% | 71.0 B/s | 1.0 B | 00m00s
[2/2] Removing cowsay-0:3.8.4-5.fc44.no 100% | 2.4 KiB/s | 63.0 B | 00m00s
Complete!
$ dnf list --installed | grep -c perl
61
预演 autoremove 能收回什么:
$ dnf autoremove --assumeno
Package Arch Version Repository Size
Removing:
groff-base x86_64 0:1.23.0-12.fc44 fedora 3.9 MiB
ncurses x86_64 0:6.6-1.fc44 fedora 611.4 KiB
perl-AutoLoader noarch 0:5.74-525.fc44 updates 20.6 KiB
perl-B x86_64 0:1.89-525.fc44 updates 501.2 KiB
perl-Carp noarch 0:1.54-521.fc44 fedora 46.6 KiB
perl-Class-Struct noarch 0:0.68-525.fc44 updates 25.4 KiB
perl-Data-Dumper x86_64 0:2.192-523.fc44 updates 115.5 KiB
perl-Digest noarch 0:1.20-521.fc44 fedora 35.3 KiB
perl-Digest-MD5 x86_64 0:2.59-521.fc44 fedora 59.6 KiB
perl-DynaLoader x86_64 0:1.57-525.fc44 updates 32.1 KiB
perl-Encode x86_64 4:3.21-521.fc44 fedora 4.7 MiB
perl-Errno noarch 0:1.38-525.fc44 updates 8.4 KiB
……(中间略)……
Removing: 63 packages
After this operation, 28 MiB will be freed (install 0 B, remove 28 MiB).
Operation aborted by the user.
$ echo $?
1
真实清理:
$ dnf autoremove -y
……(中间略)……
[63/64] Removing ncurses-0:6.6-1.fc44.x 100% | 1.6 KiB/s | 46.0 B | 00m00s
[64/64] Removing groff-base-0:1.23.0-12 100% | 4.9 KiB/s | 231.0 B | 00m00s
Complete!
$ echo $?
0
$ dnf list --installed | grep -c perl
0
解读:63 个孤儿包、28 MiB,一条 autoremove 全部收回。--no-autoremove(remove 的选项)与 autoremove(独立子命令)是同一枚硬币的两面:前者"删主包留依赖",后者"专收依赖"。生产机器上 autoremove 前务必先 --assumeno 过目清单——孤儿判定依赖"安装原因"标记,人工 rpm -ivh 装的包会被视为用户安装、不会被误删,但被 mark 改过原因的包会改变结局(mark 实测见 3.20)。
3.12 upgrade:升级
upgrade 升级指定包或全系统;update 是它的别名。全量升级预演(截取头尾):
$ dnf upgrade --assumeno
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Upgrading:
ca-certificates noarch 0:2026.2.90_v9.0.317-1.fc44 updates 2.7 MiB
replacing ca-certificates noarch 0:2025.2.80_v9.0.304-7.fc44 0eae96ab45874228a86a12a132e699ed 2.7 MiB
curl x86_64 0:8.18.0-14.fc44 updates 480.0 KiB
replacing curl x86_64 0:8.18.0-8.fc44 0eae96ab45874228a86a12a132e699ed 480.0 KiB
dnf5 x86_64 0:5.4.6.0-1.fc44 updates 3.4 MiB
replacing dnf5 x86_64 0:5.4.3.0-2.fc44 0eae96ab45874228a86a12a132e699ed 3.3 MiB
dnf5-plugins x86_64 0:5.4.6.0-1.fc44 updates 1.6 MiB
replacing dnf5-plugins x86_64 0:5.4.3.0-2.fc44 0eae96ab45874228a86a12a132e699ed 1.6 MiB
……(中间略)……
Total size of inbound packages is 21 MiB. Need to download 21 MiB.
After this operation, 1 MiB extra will be used (install 67 MiB, remove 65 MiB).
Operation aborted by the user.
$ echo $?
1
单包升级(已是最新时):
$ rpm -q tar
tar-1.35-9.fc44.x86_64
$ dnf upgrade -y tar
Updating and loading repositories:
Repositories loaded.
Nothing to do.
$ rpm -q tar
tar-1.35-9.fc44.x86_64
解读:Upgrading 区块里每个新版本下面缩进行是"replacing 被替换的旧版",旧版行尾的长哈希再次表明旧包来自装机时刻的仓库。Nothing to do. 不算错误(退出码 0)。跨大版本升级不用 upgrade,用 dnf system-upgrade 子命令(本文不展开,注意 --releasever 配合它才是正确姿势,单包场景见 3.15)。
3.13 check-update:只查不升,脚本专用
check-update(本名 check-upgrade)列出可升级项但不做任何改动,专为巡检脚本设计。它的退出码有特殊约定,实测(当时确有可用更新):
$ dnf check-update
Updating and loading repositories:
Repositories loaded.
Upgrades
ca-certificates.noarch 2026.2.90_v9.0.317-1.fc44 updates
curl.x86_64 8.18.0-14.fc44 updates
dnf5.x86_64 5.4.6.0-1.fc44 updates
dnf5-plugins.x86_64 5.4.6.0-1.fc44 updates
elfutils-default-yama-scope.noarch 0.196-1.fc44 updates
elfutils-libelf.x86_64 0.196-1.fc44 updates
elfutils-libs.x86_64 0.196-1.fc44 updates
fedora-gpg-keys.noarch 44-2 updates
fedora-repos.noarch 44-2 updates
glib2.x86_64 2.88.4-1.fc44 updates
glibc.x86_64 2.43-9.fc44 updates
glibc-common.x86_64 2.43-9.fc44 updates
glibc-minimal-langpack.x86_64 2.43-9.fc44 updates
libcap-ng.x86_64 0.9.6-1.fc44 updates
libcurl.x86_64 8.18.0-14.fc44 updates
$ echo $?
100
解读:退出码 100 = 有可用更新,0 = 全部最新,1 = 出错。这是 yum 时代沿用至今的约定,巡检脚本据此分支:if dnf check-update -q >/dev/null; then echo 最新; else echo 有更新待装; fi(100 走 else 分支)。输出格式与 dnf list --upgrades 相同,想要更结构化的数据可改用 dnf repoquery --upgrades。
顺带验证两个易错点:dnf help 子命令不存在;参数缺失是退出码 2:
$ dnf help upgrade
Unknown argument "help" for command "dnf5". Add "--help" for more information about the arguments.
It could be a command provided by a plugin, try: dnf5 install 'dnf5-command(help)'
$ echo $?
2
$ dnf install
Missing positional argument "specs" for command "install". Add "--help" for more information about the arguments.
$ echo $?
2
$ dnf
Missing command. Add "--help" for more information about the arguments.
$ echo $?
2
3.14 reinstall:重装
文件损坏、误删配置后的标准修复手段——同版本号重新落一遍盘:
$ dnf reinstall -y tree
Updating and loading repositories:
Repositories loaded.
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 0 B extra will be used (install 120 KiB, remove 120 KiB).
Package Arch Version Repository Size
Reinstalling:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
replacing tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Reinstalling: 1 package
Replacing: 1 package
[1/1] tree-0:2.2.1-4.fc44.x86_64 100% | 139.5 KiB/s | 62.7 KiB | 00m00s
--------------------------------------------------------------------------------
[1/1] Total 100% | 37.1 KiB/s | 62.7 KiB | 00m02s
Running transaction
[1/4] Verify package files 100% | 0.0 B/s | 1.0 B | 00m00s
[2/4] Prepare transaction 100% | 222.0 B/s | 2.0 B | 00m00s
[3/4] Reinstalling tree-0:2.2.1-4.fc44. 100% | 6.2 MiB/s | 121.4 KiB | 00m00s
[4/4] Removing tree-0:2.2.1-4.fc44.x86_ 100% | 375.0 B/s | 9.0 B | 00m00s
Complete!
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
对未安装的包与不存在的包都会拒绝(实测退出码均 1):
$ dnf reinstall --assumeno cowsay
Updating and loading repositories:
Repositories loaded.
Failed to resolve the transaction:
Packages for argument 'cowsay' available, but not installed.
$ dnf reinstall --assumeno nosuchpkg-404
Updating and loading repositories:
Repositories loaded.
Failed to resolve the transaction:
No match for argument: nosuchpkg-404
You can try to add to command line:
--skip-unavailable to skip unavailable packages
解读:回显里 After this operation, 0 B extra will be used (install 120 KiB, remove 120 KiB) 精确表达了"重装不占新空间"。注意 dnf5 的报错文案区分了两种失败:available, but not installed(包存在但你没装过, reinstall 无从谈起)与 No match for argument(仓库里根本没有)。后者会贴心提示 --skip-unavailable,但那会静默跳过目标包,脚本里慎用(实测见 3.20)。
3.15 downgrade:降级(含 --releasever 实测)
降级是排障刚需(新版有问题回退旧版)。难点在于:官方源通常只保留最新版本,同源没有更低版本时 downgrade 会拒绝执行。实测两种情形。
情形一:同仓库内没有更低版本:
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
$ dnf downgrade --assumeno tree
Updating and loading repositories:
Repositories loaded.
Failed to resolve the transaction:
The lowest available version of the "tree.x86_64" package is already installed, cannot downgrade it.
Nothing to do.
$ echo $?
0
情形二:用 --releasever=43 把仓库指向上一版 Fedora 43(其源里存有 tree 2.2.1-2.fc43),先预演:
$ dnf --releasever=43 downgrade --assumeno tree
……(略,预演事务与真跑输出一致,见下)……
真实降级:
$ dnf --releasever=43 -y downgrade tree
Updating and loading repositories:
Fedora 43 - x86_64 100% | 5.6 MiB/s | 36.6 MiB | 00m06s
Fedora 43 openh264 (From Cisco) - x86_ 100% | 1.9 KiB/s | 5.3 KiB | 00m02s
Repositories loaded.
Package Arch Version Repository Size
Downgrading:
tree x86_64 0:2.2.1-2.fc43 fedora 120.0 KiB
replacing tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Downgrading: 1 package
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 0 B extra will be used (install 120 KiB, remove 120 KiB).
[1/1] tree-0:2.2.1-2.fc43.x86_64 100% | 406.8 KiB/s | 62.7 KiB | 00m00s
--------------------------------------------------------------------------------
[1/1] Total 100% | 110.7 KiB/s | 62.7 KiB | 00m01s
Running transaction
[1/4] Verify package files 100% | 0.0 B/s | 1.0 B | 00m00s
[2/4] Prepare transaction 100% | 125.0 B/s | 1.0 B | 00m00s
[3/4] Downgrading tree-0:2.2.1-2.fc43.x 100% | 1.9 MiB/s | 120.0 KiB | 00m00s
[4/4] Removing tree-0:2.2.1-4.fc44.x86_ 100% | 375.0 B/s | 9.0 B | 00m00s
Complete!
$ rpm -q tree
tree-2.2.1-2.fc43.x86_64
升回最新版收尾:
$ dnf upgrade -y tree
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Upgrading:
tree x86_64 0:2.2.1-4.fc44 updates 120.0 KiB
replacing tree x86_64 0:2.2.1-2.fc43 fedora 120.0 KiB
……(中间略)……
Complete!
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
解读:Downgrading 区块结构与 upgrade 的镜像对称;--releasever 只影响元数据 URL 里的发行版变量(repo 文件里的 $releasever),不改变本机 rpmdb——所以严格说这是"从 F43 源装旧包",不是系统回退。它适合单包应急回退;整系统跨版本回退没有官方支持路径(Fedora 只支持向前 system-upgrade)。
⚠️ 注意情形一的退出码是 0 而非报错退出:cannot downgrade it + Nothing to do. 被视为"无事可做"而非失败,脚本判断降级是否发生要靠 rpm -q 比对版本,不能只看 $?。
💡 --releasever 与 installroot 的组合:dnf 支持给另一个根目录装系统(--installroot=/mnt/sysimage --releasever=44),救援盘修复系统、构建镜像时用。本文 3.19 的 config-manager 实测也顺带验证了 --releasever 对 URL 变量的替换效果(回显里仓库名直接变成 Fedora 43)。
3.16 download 与 --downloadonly:把包拿回来
download 把 rpm 落到当前目录(不进 rpmdb),是离线分发、内网补丁包制作的基础命令:
$ dnf download cowsay
Updating and loading repositories:
Repositories loaded.
Downloading Packages:
cowsay-0:3.8.4-5.fc44.noarch 100% | 368.3 KiB/s | 54.5 KiB | 00m00s
$ ls -l
total 60
-rw-r--r-- 1 root root 55823 Oct 17 00:17 cowsay-3.8.4-5.fc44.noarch.rpm
--url 只打印下载地址不落盘(注意地址是镜像调度的结果):
$ dnf download --url cowsay
Updating and loading repositories:
Repositories loaded.
https://mirror.nyist.edu.cn/fedora/releases/44/Everything/x86_64/os/Packages/c/cowsay-3.8.4-5.fc44.noarch.rpm
$ ls | wc -l
1
--resolve 连依赖一起解析下载(64 个 rpm 全部落到当前目录,这里列前几个):
$ dnf download --resolve cowsay
$ ls *.rpm | wc -l
64
$ ls -l | sed -n '1,7p'
total 9072
-rw-r--r-- 1 root root 55823 Oct 17 00:17 cowsay-3.8.4-5.fc44.noarch.rpm
-rw-r--r-- 1 root root 1177840 Oct 17 00:17 groff-base-1.23.0-12.fc44.x86_64.rpm
-rw-r--r-- 1 root root 440103 Oct 17 00:17 ncurses-6.6-1.fc44.x86_64.rpm
-rw-r--r-- 1 root root 21040 Oct 17 00:17 perl-AutoLoader-5.74-525.fc44.noarch.rpm
-rw-r--r-- 1 root root 181378 Oct 17 00:17 perl-B-1.89-525.fc44.x86_64.rpm
-rw-r--r-- 1 root root 29473 Oct 17 00:17 perl-Carp-1.54-521.fc44.noarch.rpm
另一条路:install --downloadonly 只下载进包缓存,不安装:
$ dnf install --downloadonly -y tree
Updating and loading repositories:
Repositories loaded.
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
The operation will only download packages for the transaction.
Package Arch Version Repository Size
Installing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Installing: 1 package
[1/1] tree-0:2.2.1-4.fc44.x86_64 100% | 406.8 KiB/s | 62.7 KiB | 00m00s
--------------------------------------------------------------------------------
[1/1] Total 100% | 110.7 KiB/s | 62.7 KiB | 00m01s
Complete!
$ dnf list --installed tree
No matching packages to list
$ find /var/cache/libdnf5 -name '*.rpm'
/var/cache/libdnf5/fedora-cff72538bc9825a4/packages/tree-2.2.1-4.fc44.x86_64.rpm
解读与差异表:
| 维度 | dnf download [--resolve] | dnf install --downloadonly |
|---|---|---|
| 落盘位置 | 当前目录(或 --destdir) | /var/cache/libdnf5/<repo>/packages/ |
| 依赖解析 | 可选(加 --resolve) | 总是解析完整事务 |
| 后续用法 | 拷走离线装(dnf install *.rpm/rpm -Uvh) | 直接 dnf install 时命中缓存免下载 |
--url 支持 | 支持(只打印地址) | 不支持 |
--resolve 默认跳过已安装的依赖,要强制全量下载加 --alldeps;--url 配合 --allmirrors 可打印所有镜像候选,配合 --urlprotocol=https 可过滤协议。本文实测下载地址落在 mirror.nyist.edu.cn,而 3.3 的 repo info 显示候选列表首位是 mirrors.qlu.edu.cn——不同命令、不同时刻选中的镜像可能不同,都是 metalink 正常调度。
3.17 group 与 environment:软件组管理
软件组(comps group)是仓库元数据里预定义的包集合,装一组应用不用逐个点名。查看组与组内容:
$ dnf group list | sed -n '1,22p'
Updating and loading repositories:
Repositories loaded.
ID Name Installed
neuron-modelling-simulators Neuron Modelling Simulators no
kde-education KDE Educational applications no
kde-media KDE Multimedia support no
kde-mobile KDE Mobile no
kde-mobile-apps KDE Mobile Apps no
kde-office KDE Office no
kde-pim KDE PIM no
kde-software-development KDE Software Development no
kf6-software-development KDE Frameworks 6 Software Development no
libreoffice LibreOffice no
mate-applications MATE Applications no
milkymist Milkymist no
network-server Network Servers no
kde-desktop KDE no
office Office/Productivity no
python-classroom Python Classroom no
python-science Python Science no
robotics-suite Robotics no
rpm-development-tools RPM Development Tools no
security-lab Security Lab no
sound-and-video Sound and Video no
$ dnf group list | wc -l
53
环境组(比组更高一级的"套装",如整个桌面环境):
$ dnf environment list | sed -n '1,10p'
Updating and loading repositories:
Repositories loaded.
ID Name Installed
custom-environment Fedora Custom Operating System no
workstation-product-environment Fedora Workstation no
server-product-environment Fedora Server Edition no
cloud-server-environment Fedora Cloud Server no
kde-desktop-environment KDE Plasma Workspaces no
kde-mobile-environment KDE Plasma Mobile no
xfce-desktop-environment Xfce Desktop no
phosh-desktop-environment Phosh Desktop no
lxde-desktop-environment LXDE Desktop no
组详情(text-internet 组,只含可选包):
$ dnf group info text-internet
Updating and loading repositories:
Repositories loaded.
Id : text-internet
Name : Text-based Internet
Description : This group includes text-based email, web, and chat clients. These applications do not require the X Window System.
Installed : yes
Order :
Langonly :
Uservisible : yes
Repositories : @System
Optional packages : abook
: alpine
: argus
: aria2
: axel
: cadaver
: centerim
: elinks
: epic
: fetchmail
: fpaste
: iperf
: irssi
: isync
: lftp
: lynx
: mailprocessing
: mutt
: ncftp
: nmh
: offlineimap
: rss2email
: rtorrent
: slrn
: snownews
: tftp
: tin
: w3m
: websec
: whatmask
: wondershaper
: youtube-dl
组的安装是幂等的——已安装再装一次只做确认:
$ dnf group install -y text-internet
Updating and loading repositories:
Repositories loaded.
Group "text-internet" is already installed.
Nothing to do.
$ dnf group list --installed
Updating and loading repositories:
Repositories loaded.
ID Name Installed
text-internet Text-based Internet yes
$ dnf group remove -y text-internet
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Removing groups:
Text-based Internet
Transaction Summary:
After this operation, 0 B extra will be used (install 0 B, remove 0 B).
Running transaction
Complete!
text-internet 只含 Optional 包(组安装不装可选包),所以装与删都只是"组标记"的进出,0 字节变化。下面换 fonts 组演示真实的组安装——它默认列表里看不到(grep -cw fonts 为 0),是个隐藏组:
$ dnf group list | grep -cw fonts
0
$ dnf group list --hidden | grep -w fonts
legacy-fonts Legacy Fonts no
fonts Fonts no
$ dnf group info fonts | sed -n '1,26p'
Updating and loading repositories:
Repositories loaded.
Id : fonts
Name : Fonts
Description : Fonts packages for rendering text on the desktop.
Installed : no
Order :
Langonly :
Uservisible : no
Repositories : fedora, updates
Default packages : default-fonts-cjk-mono
: default-fonts-cjk-sans
: default-fonts-cjk-serif
: default-fonts-core-emoji
: default-fonts-core-math
: default-fonts-core-mono
: default-fonts-core-sans
: default-fonts-core-serif
: default-fonts-other-mono
: default-fonts-other-sans
: default-fonts-other-serif
$ dnf group install -y fonts
Package Arch Version Repository Size
Installing group/module packages:
default-fonts-cjk-mono noarch 0:4.3-1.fc44 fedora 424.0 B
default-fonts-cjk-sans noarch 0:4.3-1.fc44 fedora 2.2 KiB
default-fonts-cjk-serif noarch 0:4.3-1.fc44 fedora 417.0 B
default-fonts-core-emoji noarch 0:4.3-1.fc44 fedora 338.0 B
default-fonts-core-math noarch 0:4.3-1.fc44 fedora 334.0 B
default-fonts-core-mono noarch 0:4.3-1.fc44 fedora 371.0 B
……(中间略)……
[137/137] Installing default-fonts-core 100% | 113.0 KiB/s | 18.2 KiB | 00m00s
Complete!
$ rpm -qa | grep -c font
135
安装后验证一个反直觉现象——隐藏组即使装上了也不出现在 group list --installed 里:
$ dnf group list --installed
Updating and loading repositories:
Repositories loaded.
卸载收尾:
$ dnf group remove -y fonts
……(中间略)……
[135/136] Removing fonts-filesystem-1:5 100% | 4.9 KiB/s | 5.0 B | 00m00s
[136/136] Removing google-noto-fonts-co 100% | 235.0 B/s | 4.0 B | 00m00s
Complete!
$ rpm -qa | grep -c font
0
解读:组元数据把包分四档——Mandatory(必装,缺失会警告)、Default(默认装)、Optional(默认不装)、Extra(特殊规则);fonts 组全部是 Default 档,所以一次装入 137 个包。判断"某组会装多少东西"先 group info 看分档,别拿组名猜。隐藏组(Uservisible: no)是给依赖关系用的"内部组",确认其状态要么 group list --hidden,要么 group info 看 Installed 字段。
💡 group 与 environment 的层级:environment(环境组)= 若干 group 的集合 + 若干默认组开关,如 server-product-environment(Fedora Server Edition)就是一组服务类 group 的打包。装机用 dnf install @server-product-environment 或安装器选环境;运维中 environment 不常动,group 才是日常单位。@组名 这种前缀写法与 dnf group install 组名 等价(install 的 specs 参数格式 <package-spec>|@<group-spec>|@<environment-spec>,见 3.9 的 --help)。
3.18 history:事务历史与 undo/rollback
dnf5 把每次事务记入历史库(含命令行、时间、影响的包),并支持反向执行。先看子命令面:
$ dnf history --help
Usage:
dnf5 [GLOBAL OPTIONS] history <COMMAND> ...
Query Commands:
list List transactions
info Print details about transactions
Software Management Commands:
undo Revert all actions from the specified transaction
redo Repeat all actions from the specified transaction
rollback Undo all transactions performed after the specified transaction
store [experimental] Store transaction to a file
记录当前基线事务号,然后连续安装两个包制造现场:
$ dnf history list | sed -n '1,3p'
ID Command line Date and time Action(s) Altered
30 dnf group remove -y fonts 2026-10-17 00:18:17 136
29 dnf group install -y fonts 2026-10-17 00:18:16 136
$ dnf install -y figlet | tail -3
Running transaction
[3/3] Installing figlet-0:2.2.5-39.fc44 100% | 15.4 MiB/s | 679.5 KiB | 00m00s
Complete!
$ dnf install -y sl | tail -3
Running transaction
[3/3] Installing sl-0:5.02-25.fc44.x86_ 100% | 783.9 KiB/s | 22.7 KiB | 00m00s
Complete!
$ dnf history list | sed -n '1,8p'
ID Command line Date and time Action(s) Altered
32 dnf install -y sl 2026-10-17 00:18:28 1
31 dnf install -y figlet 2026-10-17 00:18:27 1
30 dnf group remove -y fonts 2026-10-17 00:18:17 136
29 dnf group install -y fonts 2026-10-17 00:18:16 136
28 dnf group remove -y text-internet 2026-10-17 00:18:05 1
27 dnf remove -y tree 2026-10-17 00:17:35 1
26 dnf upgrade -y tree 2026-10-17 00:17:34 2
事务详情(含前后 rpmdb 哈希):
$ dnf history info 32
Transaction ID : 32
Begin time : 2026-10-17 00:18:28
Begin rpmdb : 47a4aa1ddddaf5e4b58e8a676caef5d5571cd2a196dacd6831fc0ccecc47d136
End time : 2026-10-17 00:18:28
End rpmdb : 7502f001b18332f8aa322d089e8162116fbafb596d3bfe2d01a65cfe40fe3e33
User : 0 Super User <root>
Status : Ok
Releasever : 44
Description : dnf install -y sl
Comment :
Packages altered:
Action Package Reason Repository
Install sl-0:5.02-25.fc44.x86_64 User fedora
undo 撤销单个事务(只回退 sl,figlet 保留):
$ dnf -y history undo 32
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Removing:
sl x86_64 0:5.02-25.fc44 fedora 21.2 KiB
Transaction Summary:
Removing: 1 package
After this operation, 21 KiB will be freed (install 0 B, remove 21 KiB).
Running transaction
[1/2] Prepare transaction 100% | 100.0 B/s | 1.0 B | 00m00s
[2/2] Removing sl-0:5.02-25.fc44.x86_64 100% | 400.0 B/s | 10.0 B | 00m00s
Complete!
$ rpm -q sl
package sl is not installed
$ rpm -q figlet
figlet-2.2.5-39.fc44.x86_64
rollback 回滚到基线事务 30(撤销 30 之后发生的一切,即把 figlet 也撤掉):
$ dnf -y history rollback 30
After this operation, 669 KiB will be freed (install 0 B, remove 669 KiB).
Running transaction
[1/2] Prepare transaction 100% | 100.0 B/s | 1.0 B | 00m00s
[2/2] Removing figlet-0:2.2.5-39.fc44.x 100% | 2.9 KiB/s | 77.0 B | 00m00s
Complete!
$ rpm -q figlet
package figlet is not installed
undo/rollback 本身也各留痕一条,last 关键字与区间写法都可用:
$ dnf history list | sed -n '1,7p'
ID Command line Date and time Action(s) Altered
34 dnf -y history rollback 30 2026-10-17 00:18:29 1
33 dnf -y history undo 32 2026-10-17 00:18:29 1
32 dnf install -y sl 2026-10-17 00:18:28 1
31 dnf install -y figlet 2026-10-17 00:18:27 1
30 dnf group remove -y fonts 2026-10-17 00:18:17 136
29 dnf group install -y fonts 2026-10-17 00:18:16 136
$ dnf history info last | sed -n '1,8p'
Transaction ID : 34
Begin time : 2026-10-17 00:18:29
Begin rpmdb : 47a4aa1ddddaf5e4b58e8a676caef5d5571cd2a196dacd6831fc0ccecc47d136
End time : 2026-10-17 00:18:29
End rpmdb : 9fa9d614474001e7d901c2ec30ce166418457acbf93e5e97eb12e22bbb9de609
User : 0 Super User <root>
Status : Ok
$ dnf history info 30..31 | sed -n '1,6p'
Transaction ID : 31
Begin time : 2026-10-17 00:18:27
Begin rpmdb : 9fa9d614474001e7d901c2ec30ce166418457acbf93e5e97eb12e22bbb9de609
End time : 2026-10-17 00:18:27
End rpmdb : 47a4aa1ddddaf5e4b58e8a676caef5d5571cd2a196dacd6831fc0ccecc47d136
解读:undo 32 = 反向执行 32 号事务;rollback 30 = 反向执行 30 号之后的所有事务,两者都生成新事务留痕(33、34 号),历史只增不改。Status: Ok 之外还可能出现 Undo 等状态标记;Begin rpmdb/End rpmdb 的哈希可用来核对两次事务之间 rpmdb 是否被第三方(如手工 rpm 命令)动过——审计时非常值钱。store/replay 是 dnf5 新增的实验特性:把事务存成目录,拿到另一台机器重放,适合批量装机场景,生产使用前先在测试机验证。
💡 undo 的边界:undo 反向求解"把当时的包集合变回去",如果该事务涉及包在当前仓库已下架,undo 可能求解失败——历史回滚不是时光机,它依赖当下可用的仓库。核心库升级这类不可逆事务,undo 前务必先 history info 看清单再动手。
3.19 config-manager:仓库启用/禁用与新增(dnf5 新语法)
dnf5 的 config-manager 从 dnf4 的"一长串短横线选项"改成了子命令结构:
$ dnf config-manager --help
Usage:
dnf5 [GLOBAL OPTIONS] config-manager <COMMAND> ...
Description:
Manage main and repositories configuration, variables and add new repositories.
Commands:
addrepo Add repositories from the specified configuration file or define a new repository using user options
setopt Set configuration and repositories options
unsetopt Unset/remove configuration and repositories options
setvar Set variables
unsetvar Unset/remove variables
enable Enables repositories
disable Disables repositories
旧语法已死——dnf4 的 --set-enabled 在 dnf5 直接报错:
$ dnf config-manager --set-enabled fedora-source
Unknown argument "--set-enabled" for command "config-manager". Add "--help" for more information about the arguments.
$ echo $?
2
新语法启用 fedora-source 源:
$ dnf config-manager enable fedora-source
$ dnf repolist
repo id repo name
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
fedora-source Fedora 44 - Source
updates Fedora 44 - x86_64 - Updates
再看持久化写到了哪里——这是 dnf5 与 dnf4 的关键行为差异(--set-enabled 在 dnf4 里是改 /etc/yum.repos.d/*.repo,dnf5 是写覆盖层)。enable 之后覆盖层文件内容:
$ cat /etc/dnf/repos.override.d/99-config_manager.repo
# Generated by libdnf5.
# Do not modify this file manually, use dnf5 config-manager instead.
[fedora-source]
enabled=1
disable 之后再看同一文件(.repo 原文件自始至终未被改动):
$ dnf config-manager disable fedora-source
$ cat /etc/dnf/repos.override.d/99-config_manager.repo
# Generated by libdnf5.
# Do not modify this file manually, use dnf5 config-manager instead.
[fedora-source]
enabled=0
恢复默认后 repolist 复核:
$ dnf repolist
repo id repo name
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
updates Fedora 44 - x86_64 - Updates
setopt 改仓库级选项,实测 updates.metadata_expire=4h:
$ dnf config-manager setopt updates.metadata_expire=4h
$ echo $?
0
$ grep -rn 'metadata_expire' /etc/dnf/repos.override.d/ 2>/dev/null
/etc/dnf/repos.override.d/99-config_manager.repo:6:metadata_expire=4h
$ dnf --dump-repo-config=updates | grep metadata_expire
metadata_expire = 14400
$ dnf config-manager unsetopt updates.metadata_expire
$ dnf --dump-repo-config=updates | grep metadata_expire
metadata_expire = 21600
但 main 主配置不支持 setopt(与 dnf4 不同,实测报错):
$ dnf config-manager setopt main.keepcache=True
ConfigManagerError: Cannot set repository option "main.keepcache=True": Option "keepcache" not found
$ echo $?
1
变量管理 setvar/unsetvar(格式为 变量名=值 单参数):
$ dnf config-manager setvar my_test_var=hello44
$ cat /etc/dnf/vars/my_test_var
hello44
$ dnf --dump-variables | grep my_test_var
my_test_var = hello44
$ dnf config-manager unsetvar my_test_var
addrepo 添加仓库:先做一个真实可用的本地源——用 createrepo_c 把一个下载好的 rpm 做成仓库,写成 repo 文件,再交给 config-manager 收编:
$ dnf install -y createrepo_c | tail -2
[5/5] Installing createrepo_c-0:1.2.1-5.fc44.x86_6 100% | 6.4 MiB/s | 197.9 KiB | 00m00s
Complete!
$ dnf download tree
Updating and loading repositories:
Repositories loaded.
Downloading Packages:
tree-0:2.2.1-4.fc44.x86_64 100% | 420.5 KiB/s | 62.7 KiB | 00m00s
$ mv tree-*.rpm /root/demo/dnf/localrepo/
$ createrepo_c /root/demo/dnf/localrepo | tail -2
Pool started (with 5 workers)
Pool finished
$ ls /root/demo/dnf/localrepo/repodata/ | sed -n '1,4p'
0d62093d533cf4ccf5992db32be5ceedfdbe95fd9e481668df7a6b47102baaf8-primary.xml.zst
b775a7aa8278a10a8b3ee6312ff70ad80d8eaead9476670b069bb67475696dc4-filelists.xml.zst
b95fbdf0548a511982b3b94b587296d51af139aaa30e3b534664f02f83d84ec9-other.xml.zst
repomd.xml
$ cat > /root/demo/dnf/local.repo <<'EOF'
[demo-local]
name=Demo Local Repo
baseurl=file:///root/demo/dnf/localrepo
enabled=1
gpgcheck=0
EOF
$ dnf config-manager addrepo --from-repofile=file:///root/demo/dnf/local.repo
file:///root/demo/dnf/local.repo 100% | 0.0 B/s | 95.0 B | 00m00s
$ dnf repolist
repo id repo name
demo-local Demo Local Repo
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
updates Fedora 44 - x86_64 - Updates
$ ls -l /etc/yum.repos.d/ | grep local
-rw-r--r-- 1 root root 95 Oct 17 00:18 local.repo
从"仅本地源"安装验证闭环(先把 tree 卸掉):
$ dnf remove -y tree | tail -1
Complete!
$ dnf --disablerepo='*' --enablerepo=demo-local install -y tree
Updating and loading repositories:
Demo Local Repo 100% | 2.3 MiB/s | 2.4 KiB | 00m00s
Repositories loaded.
Package Arch Version Repository Size
Installing:
tree x86_64 0:2.2.1-4.fc44 demo-local 120.0 KiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
[1/1] tree-0:2.2.1-4.fc44.x86_64 100% | 0.0 B/s | 62.7 KiB | 00m00s
--------------------------------------------------------------------------------
[1/1] Total 100% | 0.0 B/s | 62.7 KiB | 00m00s
Running transaction
[1/3] Verify package files 100% | 0.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 111.0 B/s | 1.0 B | 00m00s
[3/3] Installing tree-0:2.2.1-4.fc44.x8 100% | 4.4 MiB/s | 121.4 KiB | 00m00s
Warning: skipped OpenPGP checks for 1 package from repository: demo-local
Complete!
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
清理演示仓库:
$ dnf remove -y tree | tail -1
Complete!
$ rm -f /etc/yum.repos.d/demo-local.repo /etc/yum.repos.d/local.repo
$ dnf repolist
repo id repo name
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
updates Fedora 44 - x86_64 - Updates
解读与 dnf4 迁移对照表:
| 操作 | dnf4 写法 | dnf5 写法(本文实测) | 持久化位置 |
|---|---|---|---|
| 启用仓库 | config-manager --set-enabled X | config-manager enable X | /etc/dnf/repos.override.d/99-config_manager.repo |
| 禁用仓库 | config-manager --disable X | config-manager disable X | 同上 |
| 改仓库选项 | config-manager --setopt=X.opt=v | config-manager setopt X.opt=v | 同上 |
| 改 main 配置 | config-manager --setopt=main.opt=v | 不支持,直接编辑 /etc/dnf/dnf.conf | /etc/dnf/dnf.conf |
| 加仓库 | config-manager --add-repo URL | config-manager addrepo --from-repofile=仓库定义文件 | /etc/yum.repos.d/ |
| 设变量 | config-manager --setvar=X v | config-manager setvar X=v | /etc/dnf/vars/ |
Warning: skipped OpenPGP checks for 1 package from repository: demo-local 是 gpgcheck=0 的正常代价——自建源没有签名,dnf 提示但放行。公网第三方源不要学这个写法,保持 gpgcheck=1 并配好 gpgkey。
💡 override 层是 dnf5 的"配置 git stash":repos.override.d/ 里的文件由 libdnf5 生成并声明"勿手改",加载顺序在 .repo 文件之后,因此 config-manager 的改动总是生效且可整体追溯(unsetopt 即删行)。手工改 .repo 文件与 config-manager 两套写法并存时,以 override 层为准——排障时 dnf --dump-repo-config=<repo> 看到的才是"最终生效值"。
3.20 常用全局选项合集
本节集中实测横跨所有子命令的全局选项,每个都给出真实回显与结论。
(1)交互确认与 -y/--assumeyes、--assumeno。不带 -y 时会询问(printf 'n\n' 模拟手输 no):
$ printf 'n\n' | dnf install tree
Updating and loading repositories:
Repositories loaded.
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
Is this ok [y/N]: Operation aborted by the user.
$ echo $?
1
-y 与 --assumeno 同时给出时,no 优先:
$ dnf install -y --assumeno tree
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Installing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
Operation aborted by the user.
$ echo $?
1
$ dnf -y install tree | tail -3
[3/3] Installing tree-0:2.2.1-4.fc44.x8 100% | 3.0 MiB/s | 121.4 KiB | 00m00s
Complete!
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
结论:-y 脚本标配;--assumeno 是只读试跑;两者冲突时保守者胜,不会出现"既 -y 又被否"的歧义行为。
(2)mark:安装原因标记。装进来的包默认 reason 为 User,依赖为 Dep;mark 手工改档,直接影响 autoremove 的生死簿:
$ dnf mark user tree
Package "tree-2.2.1-4.fc44.x86_64" is already installed with reason "User".
Nothing to do.
$ dnf repoquery --userinstalled tree
tree-0:2.2.1-4.fc44.x86_64
(tree 已是 User 档,mark 报"已是该原因"。repoquery --userinstalled 可列出全部用户显式安装的包,做主机基线比对时很有用。)
(3)-q/--quiet 安静模式:抑制状态性输出(Updating and loading repositories: 那两行没了),查询内容保留:
$ dnf -q info cowsay | sed -n '1,6p'
Available packages
Name : cowsay
Epoch : 0
Version : 3.8.4
Release : 5.fc44
Architecture : noarch
(4)-C/--cacheonly 纯缓存模式:不联网,只用本地缓存,弱网/断网巡检可用:
$ dnf -C info cowsay | sed -n '1,8p'
Updating and loading repositories:
Repositories loaded.
Available packages
Name : cowsay
Epoch : 0
Version : 3.8.4
Release : 5.fc44
Architecture : noarch
$ echo $?
0
(缓存内已有该包元数据,查询成功;若 -C 时元数据缺失或强制过期,命令会直接失败——这是判断"缓存是否够用"的探针。)
(5)--exclude 排除通配:
$ dnf remove -y tree | tail -1
Complete!
$ dnf install --assumeno --exclude=tree tree
Updating and loading repositories:
Repositories loaded.
Failed to resolve the transaction:
Argument 'tree' matches only excluded packages.
$ echo $?
1
(6)--disablerepo / --enablerepo 临时仓库选择(等价别名 --disable-repo/--enable-repo):
$ dnf --disablerepo=updates repolist
repo id repo name
fedora Fedora 44 - x86_64
fedora-cisco-openh264 Fedora 44 openh264 (From Cisco) - x86_64
$ dnf --disablerepo='*' --enablerepo=fedora repolist
repo id repo name
fedora Fedora 44 - x86_64
(7)--skip-unavailable 与 --skip-broken:跳过"仓库里没有的包"实测有效,但跳不过"无匹配"这类求解错误:
$ dnf install --skip-unavailable --assumeno nosuchpkg-404
Updating and loading repositories:
Repositories loaded.
No match for argument: nosuchpkg-404
Nothing to do.
$ echo $?
0
$ dnf install --skip-broken --assumeno nosuchpkg-404
Updating and loading repositories:
Repositories loaded.
Failed to resolve the transaction:
No match for argument: nosuchpkg-404
You can try to add to command line:
--skip-unavailable to skip unavailable packages
$ echo $?
1
结论:--skip-unavailable 用于"装 A B C,C 可能没有"的幂等脚本(这里无匹配也返回 0);--skip-broken 解决的是依赖冲突场景(某包依赖残缺时跳过它继续),两者不要混为一谈。
(8)--best:强制选"最高可用版本"候选:
$ dnf install --best --assumeno tree
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Installing:
tree x86_64 0:2.2.1-4.fc44 fedora 120.0 KiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 63 KiB. Need to download 63 KiB.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
Operation aborted by the user.
(单包场景看不出差别;多仓库多版本并存、或指定 tree-2.1* 这类模糊 spec 时,--best 保证不为了"少动依赖"而选旧版。默认 best=0,即允许求解器挑非最优解以减少事务规模。)
(9)--dump-main-config / --dump-variables:排障透视镜:
$ dnf --dump-variables | sed -n '1,6p'
======== Variables: ========
arch = x86_64
basearch = x86_64
releasever = 44
releasever_major =
releasever_minor =
$ dnf --dump-main-config | sed -n '1,18p'
======== Main configuration: ========
allow_downgrade = 1
allow_vendor_change = 1
assumeno = 0
assumeyes = 0
autocheck_running_kernel = 1
bandwidth = 0
best = 0
bugtracker_url = https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=dnf
build_cache = 1
cachedir = /var/cache/libdnf5
cacheonly = none
check_config_file_age = 1
clean_requirements_on_remove = 1
color = auto
color_list_available_downgrade = dim,magenta
color_list_available_install = bold,cyan
color_list_available_reinstall = bold,green
顺带实测单次生效的 --setopt(注意:不带 main. 前缀、单次事务级生效,与 config-manager setopt 的持久化不同):
$ dnf --setopt=install_weak_deps=False --dump-main-config | grep '^install_weak_deps'
install_weak_deps = 0
$ dnf --setopt=main.keepcache=True --dump-main-config | grep -E '^keepcache'
No matching repositories for main. Add "--help" for more information about the arguments.
结论:--setopt=选项名=值 可单次改 main 级配置;--setopt=main.选项名=值 这个 dnf4 习惯写法在 dnf5 全局选项里同样不被接受。
(10)leaves / check / changelog:三个体检小工具:
$ dnf leaves | sed -n '1,8p'
- bzip2-0:1.0.8-23.fc44.x86_64
- createrepo_c-0:1.2.1-5.fc44.x86_64
- dnf5-0:5.4.3.0-2.fc44.x86_64
dnf5-plugins-0:5.4.3.0-2.fc44.x86_64
- gawk-0:5.3.2-3.fc44.x86_64
- rootfiles-0:9.0-6.fc44.noarch
- shadow-utils-2:4.19.0-7.fc44.x86_64
- sudo-0:1.9.17-8.p2.fc44.x86_64
$ dnf check
$ echo $?
0
$ dnf changelog tree | sed -n '5,12p'
>>> Status code: 404 for https://mirrors.qlu.edu.cn/fedora/releases/44/Everything/x86_64/os/repodata/6a37d36914955dc65cf6dc037c37dcf00c64ded464dc34164a674bf65fa16927-comps-Everything.x86_64.xml.zst (IP: 210.44.151.62) - https://mirrors.qlu.edu.cn/fedora/releases/44/Everything/x86_64/os/repodata/6a37d36914955dc65cf6dc037c37dcf00c64ded464dc34164a674bf65fa16927-comps-Everything.x86_64.xml.zst
Listing all changelogs
Changelogs for tree-2.2.1-4.fc44.x86_64
* Sat Jan 17 12:00:00 2026 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
* Thu Dec 04 12:00:00 2025 Stewart Smith <trawets@amazon.com> - 2.2.1-3
- Fix Source URL
解读:leaves 列叶子包(不再被任何已装包依赖的顶层包,行首 - 是列表标记),裁剪系统时从叶子下手;check 校验本地 rpmdb 一致性(退出码 0 即健康,排障见 FAQ);changelog 展示包的更新日志——注意它顺带暴露了一个真实世界的瑕疵:镜像的 comps 元数据 404(详见 FAQ),dnf 自动容错跳过,不影响 changelog 输出。
(11)dnf5 的日志文件:
$ ls -l /var/log/dnf5* | sed -n '1,3p'
-rw-r--r-- 1 root root 340149 Oct 17 00:21 /var/log/dnf5.log
-rw-r--r-- 1 root root 1048511 Oct 17 00:18 /var/log/dnf5.log.1
$ tail -2 /var/log/dnf5.log
2026-10-17T00:18:49+0000 [660] DEBUG No modules metadata available for repo fedora
2026-10-17T00:18:49+0000 [660] INFO DNF5 finished
/var/log/dnf5.log 按 1 MiB 轮转(.1~.4),时间戳带时区,DEBUG 级信息对定位"事务为什么这么解"很有用;更细的求解过程可用全局选项 --debugsolver 导出。
四、实战示例
以下五个场景把第三章的命令串成完整工作流,全部在实测环境跑通过。
4.1 新机初始化与补丁巡检
目标:一台刚装好的 Fedora 服务器,完成"元数据就绪 → 巡检 → 决策 → 执行 → 验证"闭环。
# 1. 元数据就绪(新机缓存为空,会全量下载)
dnf makecache
# 2. 巡检:只查不动,退出码 100=有更新 0=最新
dnf check-update
# 输出见 3.13:15 个可升级包,含 dnf5 自身与 glibc
# 3. 决策:先全量预演看清单与体积
dnf upgrade --assumeno
# 输出见 3.12:21 MiB 下载、67 MiB 落盘
# 4. 执行:夜间窗口全量升级
dnf -y upgrade
# 5. 验证:抽查关键包版本 + 确认无遗留孤儿
rpm -q dnf5 glibc
dnf autoremove --assumeno
第 4、5 步的实测回显(真实跑完全量升级):
$ dnf -y upgrade
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Upgrading:
ca-certificates noarch 0:2026.2.90_v9.0.317-1.fc44 updates 2.7 MiB
replacing ca-certificates noarch 0:2025.2.80_v9.0.304-7.fc44 0eae96ab45874228a86a12a132e699ed 2.7 MiB
curl x86_64 0:8.18.0-14.fc44 updates 480.0 KiB
replacing curl x86_64 0:8.18.0-8.fc44 0eae96ab45874228a86a12a132e699ed 480.0 KiB
……(中间 61 个升级包略,结构同上)……
[63/65] Removing glibc-0:2.43-8.fc44.x8 100% | 7.3 KiB/s | 105.0 B | 00m00s
[64/65] Removing glibc-minimal-langpack 100% | 16.3 KiB/s | 100.0 B | 00m00s
[65/65] Removing glibc-common-0:2.43-8. 100% | 38.0 B/s | 52.0 B | 00m01s
Complete!
$ rpm -q dnf5 glibc
dnf5-5.4.6.0-1.fc44.x86_64
glibc-2.43-9.fc44.x86_64
$ dnf autoremove --assumeno
Nothing to do.
$ echo $?
0
验证手段解读:rpm -q 的版本号(dnf5-5.4.6.0、glibc-2.43-9)正是 3.13 巡检清单里 updates 源给出的目标版本,说明升级闭环完成;autoremove 返回 Nothing to do.(退出码 0)说明没有孤儿遗留。另注意到全量升级把 dnf5 自身从 5.4.3.0 升到了 5.4.6.0——第三章全部回显都摄于升级前的 5.4.3.0,本节回显摄于该次升级执行过程,属同一环境的真实记录。
4.2 内网离线打补丁(download --resolve 工作流)
目标:外网机下载完整依赖闭包,拷入无外网的内网机安装。
# 外网机:下载 cowsay 及其全部未装依赖(64 个 rpm 落到当前目录)
cd /root/demo/dnf
dnf download --resolve cowsay
# 实测 64 个 rpm,清单见 3.16
# 打包传内网(scp/光碟/U盘均可)
tar cf cowsay-bundle.tar *.rpm
# 内网机:本地 rpm 直装(回显见下)
dnf install -y ./tree-2.2.1-4.fc44.x86_64.rpm
本地 rpm 直装的实测回显(用 tree 单包演示,cowsay 等多依赖包同理):
$ dnf install -y ./tree-2.2.1-4.fc44.x86_64.rpm
Updating and loading repositories:
Repositories loaded.
Total size of inbound packages is 63 KiB. Need to download 0 B.
After this operation, 120 KiB extra will be used (install 120 KiB, remove 0 B).
Running transaction
[1/3] Verify package files 100% | 0.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 111.0 B/s | 1.0 B | 00m00s
[3/3] Installing tree-0:2.2.1-4.fc44.x8 100% | 3.8 MiB/s | 121.4 KiB | 00m00s
Warning: skipped OpenPGP checks for 1 package from repository: @commandline
Complete!
Installing:
tree x86_64 0:2.2.1-4.fc44 @commandline 120.0 KiB
Transaction Summary:
Installing: 1 package
$ rpm -q tree
tree-2.2.1-4.fc44.x86_64
三个实测细节:Repository 列显示 @commandline——本地文件不经过任何仓库;Need to download 0 B——rpm 已在本地,只解依赖;Warning: skipped OpenPGP checks for 1 package from repository: @commandline——本地包默认跳过签名校验,这就是为什么外网下载的包要在可信渠道获取。事务摘要出现在 Complete! 之后是 3.10 所述 stderr/stdout 交缠现象,非异常。
验证手段:内网机 rpm -q 版本与外网机一致;若内网机提示缺依赖,说明两机 rpmdb 基线差异过大,改用 --alldeps 重新在外网机下载全量依赖。dnf download --url cowsay 可先把下载地址甩给同事复核,不用先落盘。
4.3 自建本地仓库并收编(createrepo_c + config-manager)
目标:把一批 rpm 做成正式仓库,走 dnf 标准流程管理(4.2 的进阶版,可挂内网 HTTP 长期服务)。
# 1. 备料:收集 rpm 到仓库目录
mkdir -p /srv/repo/local
cp /root/demo/dnf/*.rpm /srv/repo/local/
# 2. 生成元数据
createrepo_c /srv/repo/local
# 实测输出 Pool started (with 5 workers) / Pool finished
# 3. 写 repo 定义
cat > /etc/yum.repos.d/demo-local.repo <<'EOF'
[demo-local]
name=Demo Local Repo
baseurl=file:///srv/repo/local
enabled=1
gpgcheck=0
EOF
# 4. 刷新缓存并验证
dnf clean metadata && dnf makecache
dnf repo info demo-local
dnf --disablerepo='*' --enablerepo=demo-local list --available
# 5. 装一个验证闭环,然后看仓库报表
dnf --disablerepo='*' --enablerepo=demo-local install -y tree
dnf repoinfo
第 4 步的实测回显:
$ dnf --disablerepo='*' --enablerepo=demo-local list --available
Updating and loading repositories:
Repositories loaded.
Available packages
tree.x86_64 2.2.1-4.fc44 demo-local
$ dnf repo info demo-local
Updating and loading repositories:
Repositories loaded.
Repo ID : demo-local
Name : Demo Local Repo
Status : enabled
Priority : 99
Cost : 1000
Type : available
Metadata expire : 172800 seconds (last: 2026-10-17 00:32:42)
Skip if unavailable : true
Config file : /etc/yum.repos.d/demo-local.repo
URLs :
Base URL : file:///srv/repo/local
OpenPGP :
Verify repodata : false
Verify packages : false
实测要点:仓库目录更新后重跑 createrepo_c 即可(增量更新加 --update);list --available 输出行尾的仓库名 demo-local 证明包确实来自新仓库;repo info 里 Verify packages: false 对应 gpgcheck=0;若要走 HTTP,把 baseurl 改为 http://内网机地址/repo/local 并在仓库机起 nginx/httpd。第 5 步的安装回显与 3.19 的 demo-local 安装一致,此处不重复贴出。
4.4 误操作回滚(history undo / rollback 决策)
目标:凌晨批量安装脚本装错了包集合,需要精准回退。决策树:只撤销一条命令 → undo 那条命令的事务号;撤销某时间点之后的全部 → rollback 到那个时间点之前最后一个好事务号。
# 1. 找现场:按命令行关键字定位事务号
dnf history list | grep 'install -y sl'
# 实测:32 dnf install -y sl
# 2. 体检:确认该事务干了什么、前后 rpmdb 哈希
dnf history info 32
# 实测:仅 Install sl-0:5.02-25.fc44.x86_64,Status Ok
# 3. 撤销单事务(摘要与实测回显见 3.18)
dnf -y history undo 32
# 实测:Removing sl,Complete!,figlet 不受影响
# 4. 更大范围:回滚到基线事务 30(撤销其后全部)
dnf -y history rollback 30
# 实测:Removing figlet,Complete!
# 5. 复盘:undo/rollback 各留痕一条,last 与区间写法可用
dnf history list | sed -n '1,5p'
dnf history info last
dnf history info 30..31
验证手段:rpm -q 逐包确认;dnf history info <撤销事务号> 的 Begin rpmdb 哈希应等于被撤销事务的 Begin rpmdb(系统状态精确回到原点,3.18 实测数据即如此)。
4.5 磁盘瘦身三连(clean + autoremove + leaves)
目标:/var 告警后的标准瘦身流程,按"安全 → 谨慎 → 人工"排序。
# 1. 无风险:清缓存(元数据 + 已下载 rpm)
dnf clean all
du -sh /var/cache/libdnf5
# 实测:263 MiB 清空
# 2. 低风险:清孤儿依赖(先预演过目)
dnf autoremove --assumeno
dnf -y autoremove
# 实测:63 包 / 28 MiB(3.11)
# 3. 人工决策:叶子包里挑不再需要的显式卸载
dnf leaves
dnf remove -y createrepo_c # 例:临时工具用完即删
验证手段:df -h /var 前后对比;dnf leaves 复查叶子列表变化;切勿对 leaves 清单一把梭 dnf remove——叶子不等于没用(sudo、gawk 都在其中),必须逐个判断。
五、注意事项与常见问题
Q1:check-update 退出码 100 算失败吗? 不算。约定:0=无更新,100=有可用更新,1=真错误。监控脚本要把 100 当作正常分支处理(见 3.13)。
Q2:dnf help <命令> 报 Unknown argument?
dnf5 移除了 help 子命令(实测退出码 2,3.13),改用 dnf <命令> --help;报错里提示的 dnf5 install 'dnf5-command(help)' 是一个第三方补丁插件,按需自选。
Q3:dnf list installed 为什么报 No matching packages?
installed 不带 -- 时被当作包名模式。规范写法 dnf list --installed;若用旧写法必须跟包名:dnf list installed tree(3.6 有完整实测)。
Q4:config-manager setopt main.keepcache=True 报 Option "keepcache" not found?
dnf5 的 config-manager setopt 只支持仓库级选项,main 级配置它管不了(实测回显见 3.19)。改 main 配置:直接编辑 /etc/dnf/dnf.conf,或用单次生效的 dnf --setopt=install_weak_deps=False(注意不带 main. 前缀,实测 3.20 第 9 条)。
Q5:config-manager enable 之后,为什么 .repo 文件没变?
dnf5 把改动写进覆盖层 /etc/dnf/repos.override.d/99-config_manager.repo(文件头注明"Generated by libdnf5, Do not modify manually"),加载优先级高于 /etc/yum.repos.d/。排障时以 dnf --dump-repo-config=<repo> 为准(3.19)。
Q6:makecache 时镜像报 404(comps 元数据),要紧吗? 实测在 changelog 场景撞到过镜像 comps 元数据 404(完整逐字回显见 3.20 第 10 条,含真实镜像 IP)。这是个别镜像的 repodata 目录不全,dnf 容错后元数据照常可用,命令照常成功。若 404 密集到主元数据(primary/filelists)失败,换用其他镜像或稍后重试;国内镜像同步高峰期(发版后数日)最易出现。
Q7:不同命令打印的下载地址不一样(qlu/nyist 镜像)?
metalink 调度按当次测速选镜像,repo info 展示的候选首位、download --url 打印的地址都可能随时间变化,属正常现象(3.3 与 3.16 的实测地址就不同)。要钉死地址就自建源用 baseurl。
Q8:采集 dnf 输出到日志,顺序怎么乱了?
dnf5 把进度条与提示写 stderr、事务摘要写 stdout,管道后顺序会交叉(3.10 两个回显对比可见)。要原始顺序:dnf <子命令> 2>&1 | tee dnf.log;只关心结果:dnf -q <子命令>。
Q9:group list --installed 里找不到明明装过的组?
隐藏组(Uservisible: no)装上也不显示,实测 fonts 组安装 137 个包后该列表仍为空(3.17)。确认状态用 dnf group info <组id> 看 Installed 字段,或 dnf group list --hidden --installed。
Q10:downgrade 报 The lowest available version of the "tree.x86_64" package is already installed, cannot downgrade it.,且退出码是 0?
官方源只有最新版时无版本可降,dnf5 把它当"无事可做"(退出码 0)。真降级要给低版本来源:dnf --releasever=43 downgrade <包> 指向上一版源(3.15 全流程实测)。整系统回退没有官方路径,只有向前升级。
Q11:history undo 失败或结果与预期不符?
undo 是对当下仓库重新求解的反向事务,不是存档回放:涉及包已下架、或之后事务动过同一批文件,都可能失败或触发连带改动。 undo 前必做三件事:dnf history info <id> 过目清单、备份 /var/lib/dnf/history、小范围先试。rollback 范围更大,慎之又慎(3.18)。
Q12:autoremove 会误删我手工 rpm -ivh 装的包吗?
不会。autoremove 只动 reason 为 Dep 的包;手工 rpm 装的包 reason 为 User(外部原因),不在清理范围。可用 dnf repoquery --userinstalled 审计名单,用 dnf mark user <包> 给"其实是手动维护"的包人工改档(3.20 第 2 条)。
Q13:装包时提示 skipped OpenPGP checks 是不是被攻击了?
只在该仓库配置 gpgcheck=0 时出现(本文自建 demo-local 源即如此,3.19)。公网第三方源保持 gpgcheck=1 + gpgkey= 配置;临时跳过签名用全局 --nogpgcheck(等价 --no-gpgchecks),用完即弃。
Q14:怎么确认 rpmdb 没被人手工动过?
两条腿:dnf check 做一致性体检(健康时退出码 0、无输出,3.20);比对相邻事务的 dnf history info 里 End rpmdb 与下一条 Begin rpmdb 哈希是否一致,不一致说明中间有 dnf 体系外的 rpmdb 变更(3.18)。
Q15:镜像源能否指定国内教育网/企业源?
可以,两种姿势:临时用 --setopt 改 metalink/baseurl,或自建源(4.3)。Fedora 官方 repo 默认走 mirrors.fedoraproject.org 的 metalink 服务做全球调度(repo info 的 35 more 即镜像池,3.3),国内直连速度不佳时再动手。
Q16:dnf5 的日志在哪、多大、怎么轮转?
/var/log/dnf5.log(主日志,1 MiB 轮转,保留 .1~.4)与 /var/log/dnf5.lib.log(库级)。排障顺序:先 history(事务级)→ dnf5.log(命令级 DEBUG/INFO)→ --debugsolver(求解级,导出专用目录)。
六、参考链接
- dnf5 官方文档(命令与配置参考):https://dnf5.readthedocs.io/
- dnf5 源码仓库(issue/变更记录):https://github.com/rpm-software-management/dnf5
- 系统手册(本机可查):
man dnf5(8)、man dnf5.conf(5)、man dnf5-command(各子命令)、man createrepo_c(8) - Fedora 官方快速文档 · DNF:https://docs.fedoraproject.org/en-US/quick-docs/dnf/
- Fedora 系统升级(system-upgrade 官方指南):https://docs.fedoraproject.org/en-US/quick-docs/dnf-system-upgrade/
- Fedora 镜像列表管理(MirrorManager):https://mirrors.fedoraproject.org/