GRUB当前默认启动项由grubenv中saved_entry值决定,但仅当/etc/default/grub中GRUB_DEFAULT=saved时生效;否则该值被忽略,实际默认项由GRUB_DEFAULT直接指定。

查看 grubenv 中的 saved_entry 值
GRUB 的“当前默认启动项”实际存储在二进制环境文件 /boot/grub/grubenv(BIOS)或 /boot/efi/EFI/fedora/grubenv(UEFI,路径因发行版而异)中,而不是直接写死在配置里。最直接、最可靠的方式是用 grub-editenv 读取:
sudo grub-editenv /boot/grub/grubenv list
输出中会出现类似 saved_entry=Ubuntu, with Linux 6.8.0-45-generic 或 saved_entry=1 的行。这个值就是 GRUB 下次启动时真正会选中的项。
注意:grubenv 是小端格式二进制文件,不能用 cat 直接看;必须用 grub-editenv list,否则看到的是乱码或空内容。
确认 /etc/default/grub 中的 GRUB_DEFAULT 设置
该文件决定 GRUB 如何解释 saved_entry —— 它本身不存“默认项”,而是定义“怎么找默认项”。常见设置有:
-
GRUB_DEFAULT=0:忽略saved_entry,永远启动菜单第 0 项 -
GRUB_DEFAULT=saved:启用grub-set-default机制,以grubenv中的saved_entry为准(这是多数现代发行版的默认) -
GRUB_DEFAULT="2>1":主菜单第 2 项(通常是 “Advanced options”),再进其子菜单第 1 项
运行 grep "^GRUB_DEFAULT=" /etc/default/grub 即可快速确认。如果值不是 saved,那 grubenv 里的 saved_entry 就被无视了。
对照 grub.cfg 查看实际菜单结构
grubenv 里的 saved_entry 值(比如 "Ubuntu, with Linux 6.8.0-45-generic")必须和 /boot/grub/grub.cfg 中某个 menuentry 的完整标题完全一致(含空格、逗号、括号),否则启动时会 fallback 到第 0 项。
快速检查方法:
grep "^menuentry " /boot/grub/grub.cfg | cut -d\' -f2 | head -10
这能列出前 10 个可见菜单项标题,方便你核对 saved_entry 是否真实存在。特别注意:带 “(recovery mode)” 的条目、子菜单里的内核、以及不同发行版生成的标题格式(如 CentOS 用 CentOS Linux (5.14.0-427.13.1.el9_4.x86_64) 9)都可能和直觉不符。
用 grubby 查看内核级默认项(RHEL/CentOS/Rocky 系列)
Red Hat 系衍生发行版通常同时维护两套机制:grub 菜单逻辑 + grubby 内核元数据。它更贴近“哪个 vmlinuz 文件实际被设为默认”:
grubby --default-kernel → 输出类似 /boot/vmlinuz-5.14.0-427.13.1.el9_4.x86_64
grubby --default-index → 输出数字索引(对应 grub.cfg 中的顺序)
这个结果和 grub-editenv 可能不一致——如果系统混用了 grub-set-default 和 grubby --set-default,就说明两套状态已脱节,此时应以 grubenv 为准(因为 GRUB 启动时只读它)。
真正容易被忽略的是:GRUB 默认行为依赖 GRUB_DEFAULT 的语义解释,而不是某一个单一命令的输出。同一个 saved_entry 值,在 GRUB_DEFAULT=saved 时生效,在 GRUB_DEFAULT=0 时彻底无效。务必先看 /etc/default/grub,再查 grubenv,最后对照 grub.cfg 标题。


















