1. 项目概述:为什么GRUB启动项会“冗余”?
如果你在电脑上安装了Ubuntu,尤其是和Windows组成了双系统,那么开机时那个黑底白字的GRUB菜单你一定不陌生。它全称是GRand Unified Bootloader,是Linux世界的“引路人”,负责在电脑启动时加载操作系统内核。但有时候,这个菜单会变得“不听话”——里面塞满了你早已删除的旧系统内核条目,或者残留着已经卸载的Windows系统选项,甚至是一些你从未见过的、莫名其妙的启动项。这不仅让开机选择变得冗长混乱,更关键的是,某些损坏或无效的条目可能会导致系统引导失败,直接把你卡在开机界面。
这个问题太常见了。我见过太多朋友,在更新了几次内核,或者折腾了一番双系统后,GRUB菜单就变得像一本乱涂乱画的旧书,有用的条目和历史的“垃圾”混在一起。手动删除这些多余的GRUB启动项,并不是什么高深的黑客技术,而是一项非常基础但极其重要的系统维护技能。它关乎你电脑启动的清爽与稳定。今天,我就以一个过来人的身份,把这里面的门道、具体操作步骤,以及我踩过的那些坑,给你彻底讲明白。无论你是刚接触Ubuntu的新手,还是已经用了一段时间但被GRUB困扰的用户,这篇内容都能让你亲手驯服这个启动管理器。
2. GRUB启动项管理核心原理拆解
在动手删除任何东西之前,我们必须先搞清楚GRUB是怎么工作的。知其然更要知其所以然,这样才能在出问题时知道从哪里救回来。
2.1 GRUB 2的配置文件体系
现代的Ubuntu使用的都是GRUB 2,它的配置不再是一个单一的menu.lst文件,而是一个灵活的脚本生成体系。理解这个体系是安全操作的前提。
核心文件位于/boot/grub/和/etc/default/grub以及/etc/grub.d/目录下。
/boot/grub/grub.cfg:这是GRUB在启动时真正读取的最终配置文件。重要警告:你永远不应该直接手动编辑这个文件!因为它是被grub-mkconfig(或update-grub)命令自动生成的,任何手动修改都会在下一次系统更新或生成配置时被覆盖。/etc/default/grub:这是主要的用户配置文件。你可以在这里设置全局变量,比如默认启动项、超时时间、是否显示隐藏菜单等。我们后续的一些优化操作会在这里进行。/etc/grub.d/:这个目录里存放着一系列可执行脚本(如10_linux,30_os-prober,40_custom等)。grub-mkconfig命令会按照数字顺序执行这些脚本,并将它们的输出拼接到一起,最终生成/boot/grub/grub.cfg。10_linux负责扫描并添加当前系统安装的内核;30_os-prober则负责探测硬盘上其他操作系统(如Windows)并为其生成启动项。
当你执行sudo update-grub命令时,系统做的就是调用grub-mkconfig,根据上述脚本和配置,重新生成/boot/grub/grub.cfg文件。因此,我们“删除”启动项的本质,其实是通过修改底层配置或清理系统文件,来影响grub-mkconfig生成新菜单时的内容。
2.2 启动项来源分析:什么该删,什么该留?
GRUB菜单里的条目主要来自以下几个地方,搞清楚来源才能精准“打击”:
- 旧内核条目:这是最常见的“垃圾”。Ubuntu在更新内核时,默认会保留旧内核以防新内核启动失败。但保留2-3个就够了,半年前的内核完全可以清理。
- 已卸载系统的残留项:比如你移除了Windows系统,但
30_os-prober脚本可能还在/boot/grub/grub.cfg里留下了它的启动项,因为对应的磁盘分区或引导文件可能还在。 - 内存测试工具
memtest86+:这个工具通常有两个条目(普通版和串口控制台版),对于绝大多数桌面用户来说基本用不到,可以移除。 - 恢复模式条目:每个内核都会对应一个“recovery mode”选项,用于系统修复。这个绝对不能删除,它是系统出问题时的救命稻草。
- 自定义条目:通过
/etc/grub.d/40_custom脚本手动添加的条目。
我们的清理目标主要是前三种:冗余的旧内核、不存在的系统残留、以及无用的内存测试工具。
3. 实战操作:安全删除GRUB启动项全流程
理论说完了,现在进入实战环节。请跟着步骤一步一步来,建议在操作前,先打开一个文本编辑器记录下你当前的GRUB菜单顺序(开机时拍照或快速抄录),以便后续对照。
3.1 方法一:清理旧内核条目(最推荐、最安全)
这是最规范、最系统的方法,通过包管理器来操作,能确保依赖关系完整。
步骤1:查看当前已安装的所有内核在终端中执行:
dpkg --list | grep linux-image你会看到一个列表,显示所有已安装的linux-image包,包括版本号和状态(ii表示已安装)。类似下面这样:
ii linux-image-5.15.0-60-generic 5.15.0-60.66... amd64 Signed kernel image generic ii linux-image-5.15.0-76-generic 5.15.0-76.83... amd64 Signed kernel image generic ii linux-image-5.15.0-91-generic 5.15.0-91.102.. amd64 Signed kernel image generic ii linux-image-generic-hwe-22.04 5.15.0.91.102... amd64 Generic Linux kernel image通常,最新的内核是版本号最大的那个(例如上面的5.15.0-91)。linux-image-generic这类元包(meta-package)指向当前推荐的最新内核,不要删除它。
步骤2:删除旧内核包假设我们要保留最新的-91内核,删除更旧的-60和-76。使用apt的purge命令可以彻底删除软件包及其配置文件:
sudo apt purge linux-image-5.15.0-60-generic linux-image-5.15.0-76-generic关键技巧1:你也可以使用sudo apt autoremove命令。它会自动移除那些因为依赖关系而安装,但现在不再被任何程序需要的包。在清理旧内核后执行这个命令,常常能清理掉与之关联的linux-headers(内核头文件)和linux-modules(内核模块)包,让清理更彻底。
步骤3:更新GRUB配置删除内核包后,系统文件(主要是/boot目录下的vmlinuz-*和initrd.img-*文件)会被清理。此时再运行:
sudo update-grub这个命令会重新扫描/boot目录,发现旧内核文件已不存在,于是在生成新的grub.cfg时,就不会再为它们创建启动项了。
注意事项:务必确保你当前正在运行的内核不是你打算删除的那个。你可以用
uname -r命令查看当前内核版本。永远保留至少一个能正常启动的内核。
3.2 方法二:禁用特定GRUB生成脚本
如果你不想删除系统探测到的其他操作系统(比如Windows),但又不想让它在GRUB菜单里显示,或者想隐藏memtest86+,可以禁用对应的生成脚本。
步骤1:定位并修改脚本权限GRUB的生成脚本在/etc/grub.d/目录下。这些脚本只要具有可执行权限(chmod +x),就会被grub-mkconfig执行。我们可以通过移除可执行权限来“禁用”它。
- 禁用其他操作系统探测(如Windows):
sudo chmod -x /etc/grub.d/30_os-prober - 禁用内存测试工具:
sudo chmod -x /etc/grub.d/20_memtest86+
步骤2:重新生成GRUB配置修改权限后,再次执行:
sudo update-grub此时,被禁用脚本对应的菜单项就会从新生成的配置中消失。
实操心得:这种方法是非破坏性的,只是让脚本“沉默”。当你哪天需要重新显示这些条目时,只需使用
sudo chmod +x /脚本名恢复其可执行权限,再update-grub即可。这比直接删除脚本文件更安全。
3.3 方法三:手动编辑自定义脚本(高级)
对于通过40_custom添加的自定义条目,或者你想进行更精细的控制(比如隐藏某个特定的、已存在的内核条目),就需要手动编辑了。
步骤1:编辑自定义脚本打开/etc/grub.d/40_custom,你可以看到你自己添加的菜单项。直接删除或注释掉(在行首加#)对应的menuentry段落即可。
步骤2:处理顽固的、不想见到的现有条目这是一个更高级的技巧。假设30_os-prober探测到了一个你不想删除但也不想在菜单里看到的系统(比如另一个Linux发行版),直接禁用30_os-prober会隐藏所有其他系统。这时,你可以修改/etc/grub.d/30_os-prober脚本,在它内部添加过滤逻辑。但我不建议新手直接修改系统脚本,容易出错。
一个更安全的替代方案是:在/etc/default/grub中,添加一行:
GRUB_DISABLE_OS_PROBER=true然后运行sudo update-grub。这将完全禁用外部系统探测,效果和禁用30_os-prober脚本一样,但通过配置文件管理,更清晰。
3.4 方法四:直接调整GRUB菜单显示(治标不治本)
如果你只是觉得菜单太长,想暂时简化,可以修改/etc/default/grub文件:
sudo nano /etc/default/grub找到并修改以下两行:
GRUB_TIMEOUT_STYLE=hidden # 隐藏倒计时菜单,按Shift或Esc才显示 GRUB_TIMEOUT=0 # 将超时时间设为0秒,直接启动默认项或者,设置一个很短的超时时间(如GRUB_TIMEOUT=2)。修改后运行sudo update-grub生效。 这并没有真正删除启动项,只是让它们不显示出来。在需要时按住Shift键(BIOS系统)或Esc键(UEFI系统)启动,依然可以调出完整菜单。
4. 深度优化与GRUB环境美化
清理完冗余项,我们还可以让GRUB用起来更顺手。
4.1 设置默认启动项和超时时间
编辑/etc/default/grub:
GRUB_DEFAULT=0:默认启动第一个菜单项(从0开始计数)。你也可以设置为saved,这样GRUB会记住你上次的选择。GRUB_TIMEOUT=10:菜单等待选择的秒数。设为-1则无限等待。GRUB_CMDLINE_LINUX_DEFAULT:这里可以添加内核启动参数,例如quiet splash用于隐藏启动日志显示图形化闪屏。
一个实用技巧:如果你想默认启动上一次选择的系统,可以设置:
GRUB_DEFAULT=saved GRUB_SAVEDEFAULT=true这样每次你的选择都会被记住,下次开机自动高亮上次进入的系统。
4.2 手动调整菜单项顺序
GRUB菜单的顺序由/etc/grub.d/目录下脚本的数字前缀决定(00_,10_,30_,40_)。数字越小,生成的菜单项位置越靠前。 如果你想让自定义条目(40_custom)显示在最前面,可以把它重命名为06_custom。注意:00_header和05_debian_theme这类设置头部和主题的脚本,顺序不要乱动。
4.3 重建GRUB到磁盘主引导记录(MBR)或EFI分区
在极少数情况下,清理后GRUB菜单正常了,但系统还是无法引导(比如直接跳到了Windows,或者黑屏)。这可能是GRUB的引导程序本身损坏或位置不对。此时需要重装GRUB到磁盘。
- 对于传统BIOS/MBR引导:
sudo grub-install /dev/sdX # 请将`sdX`替换为你的系统磁盘,如`sda`, 不是分区! sudo update-grub - 对于UEFI/GPT引导:
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Ubuntu sudo update-grub/boot/efi是你的EFI系统分区(ESP)的挂载点,通常情况是这样。
5. 常见问题与故障排查实录
操作过程中难免会遇到问题,这里是我总结的一些常见“坑”和解决方法。
5.1 问题:执行sudo update-grub后,已删除的启动项又回来了!
- 原因排查:这几乎可以肯定是因为内核文件没有被真正删除。你用
apt purge删除了内核包,但/boot目录下对应的vmlinuz-*和initrd.img-*文件可能因为某些原因(如权限问题)残留了下来。update-grub的10_linux脚本扫描到这些文件,就会再次为它们生成菜单项。 - 解决方案:
- 手动检查并删除
/boot目录下的残留文件:
对照你保留的内核版本,删除那些版本号不对应的文件。操作前请再三确认!ls /boot | grep -E \"vmlinuz|initrd.img\"sudo rm /boot/vmlinuz-旧版本号-generic sudo rm /boot/initrd.img-旧版本号-generic - 再次运行
sudo update-grub。
- 手动检查并删除
5.2 问题:误删了当前正在使用的内核,导致系统无法启动
- 预防措施:在执行任何删除操作前,务必用
uname -r确认当前内核版本,并确保它不在你的删除列表里。 - 应急修复:如果已经发生,别慌。在GRUB菜单界面(如果还能看到的话),选择一个旧版本的内核或者恢复模式(recovery mode)启动。进入系统后,立即重新安装最新的内核:
或者从Ubuntu安装U盘启动,进入“试用Ubuntu”模式,然后挂载你的系统根分区,用sudo apt install --reinstall linux-image-genericchroot进去进行修复。这是更高级的操作,需要一定经验。
5.3 问题:双系统下删除Windows条目后,GRUB直接报错或进入grub rescue>模式
- 原因分析:这可能是因为你的GRUB引导信息(
core.img)被错误地安装在了Windows的引导分区上,或者grub.cfg中仍有一条指向已删除分区的启动项作为了默认项。 - 解决方案:
- 首先,尝试在GRUB菜单出现时,手动选择你的Ubuntu内核启动。
- 进入Ubuntu后,检查
/etc/default/grub中的GRUB_DEFAULT是否指向了一个不存在的菜单项索引。将其改为0。 - 重新运行
sudo grub-install(指定正确的磁盘,如/dev/sda)和sudo update-grub,确保GRUB被正确安装到你的主硬盘MBR或UEFI系统分区。 - 如果问题依旧,可能需要使用Ubuntu安装盘进行
boot-repair工具修复,这是一个图形化的强力修复工具。
5.4 问题:/boot分区空间不足,导致内核更新失败
- 背景:如果安装Ubuntu时为
/boot分配了独立分区且空间较小(比如200MB),在保留多个旧内核时很容易被填满。 - 解决思路:这正是我们清理旧内核的主要动机之一。按照3.1的方法清理旧内核包,可以立即释放
/boot分区空间。清理后,可以使用df -h /boot命令查看空间释放情况。
5.5 GRUB菜单美化与背景修改
这属于“玩”的范畴,但能让你的启动界面更个性。主要原理是替换/boot/grub/下的背景图片(通常是grub.png或wallpaper.png),并调整/etc/default/grub中的GRUB_THEME指向。网上有很多现成的GRUB主题包,安装后运行sudo update-grub即可生效。不过要注意,某些主题可能在高分辨率屏幕上显示异常。
整个GRUB启动项的管理,从清理、优化到排错,核心逻辑就是理解其“配置生成”的工作模式。安全操作的关键在于:永远通过修改源配置(/etc/default/grub,/etc/grub.d/)或通过包管理器操作,然后让update-grub命令去生成最终的grub.cfg,而不是直接对grub.cfg动刀。记住这个原则,你就能从容应对大部分GRUB相关的配置问题。