开机按下电源键屏幕没出现Ubuntu的紫色界面也没看到登录页反而停在一个黑色背景的命令行窗口提示符就三个字符grub。第一次遇见的朋友基本都会慌觉得系统是不是彻底坏了要不要直接重装。我见过不少这样的求助其实这个现象在Ubuntu用户里不算少见而且绝大多数情况根本不需要重装系统甚至不用U盘进Live环境在命令行里敲几行命令就能把系统重新拉起来。这篇文章就把整条链路讲清楚怎么区分你卡在了GRUB的哪个阶段怎么在grub提示符下手动引导系统进入系统后怎么找到根因做永久修复以及万一系统进不去时怎么用Live USB配合chroot做离线救援。无论你是Windows和Ubuntu双系统用户还是公司服务器上跑着Ubuntu的运维新手都可以按这个顺序排查一遍。1. 先确认你卡在的到底是哪一层GRUB界面1.1 三种容易混的界面别一上来就乱敲命令不少求助帖把“开机进入grub模式”混为一谈但GRUB其实有三种界面处理方式差别很大。第一种是正常的GRUB菜单紫色或黑底列出Ubuntu、Advanced options for Ubuntu、以及可能的Windows Boot Manager。这是正常状态不算问题。很多人急着把系统默认项改成直接登录反而把GRUB菜单弄没了那是另一种坑。第二种是grub命令行。GRUB核心已经加载了但它找不到可用的grub.cfg配置文件于是把你丢到一个最小命令行里。这个环境下部分模块还没加载但ls、set、insmod这些内置命令还能用所以有较大操作空间。第三种是grub rescue救援模式。这是更早期的阶段GRUB连自己的一些核心模块都没找到通常提示error: unknown filesystem或者no such partition命令也很少基本靠set和ls救场。判断方法很简单看提示符。grub和grub rescue的修复路径完全不同后面会分别说明。不要看到命令行就随便敲reboot或者乱按方向键先确认状态。1.2 为什么Ubuntu启动会经过GRUB这一关要从根上理解这个问题得先知道电脑启动的基本顺序。传统BIOS或UEFI固件启动后会按优先级寻找可启动设备找到引导加载器。Ubuntu默认用的引导加载器就是GRUB 2它负责把你选择的系统内核加载进内存再把控制权交给内核。GRUB 2的工作流程大致分两步第一步是加载自身核心第二步是从/boot/grub目录读取配置、加载文件系统模块、显示菜单。只要第二步里任何一环出问题比如配置文件损坏、分区找不到、模块路径不对GRUB就会退到命令行。打个比方GRUB像一个前台接待菜单就是前台桌上的电话本。接待本身已经站在门口了但电话本丢了他没法告诉你各个办公室在几楼只好让你直接问他。grub就是那个“你问我答但没电话本”的状态。1.3 两行命令快速判断当前状态进到grub后先别急着乱敲。第一时间输入ls这条命令会列出GRUB能识别的磁盘和分区形如(hd0)、(hd0,gpt1)、(hd0,msdos2)等。再看当前环境set这会输出root和prefix的值比如root(hd0,gpt2)、prefix(hd0,gpt2)/boot/grub。如果prefix指向的路径里确实存在grub.cfg但菜单还是没出来可以试试输入normal重新加载正常模块。如果提示file not found那就说明prefix设置不正确或者分区不对后面手动引导部分会专门讲怎么处理。2. 临时救急从grub命令行把系统重新拉起来2.1 第一招重新加载normal模块回到菜单在grub提示符下最快的恢复方式往往是normal如果GRUB的模块和配置其实都还在只是加载流程中断了这条命令会尝试重新加载正常模式直接回到熟悉的菜单界面。我有一次就是升级完内核后菜单莫名其妙消失了敲了normal就回来了全程不到十秒。如果normal提示file not found说明GRUB找不到/boot/grub下的模块文件。这时候换第二招用exit命令退出GRUB可能会回到固件的启动菜单或者直接重启方便你进入BIOS检查启动顺序。在UEFI机器上exit通常能退到固件设置界面传统BIOS机器则可能直接重启。这两个命令都不破坏任何数据可以放心试。我要提醒的是很多人到了grub会习惯性输入reboot这个命令在GRUB里不一定存在反而容易把自己绕晕。2.2 手动引导内核完整命令与每个参数的作用如果normal没用那就手动把内核加载起来。整个过程就是把GRUB应该做的引导工作自己做一遍看似命令多其实每一步都有明确含义。先用ls确认分区情况比如输出(hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3)接着逐个检查哪个分区里有/boot/grub目录。在grub下可以直接列出目录内容看看ls (hd0,gpt2)/boot/grub如果输出了一堆.mod文件和grub.cfg说明这就是GRUB的家。接下来把根指向这个分区set root(hd0,gpt2)然后加载Linux引导模块并指定内核参数insmod linux linux /boot/vmlinuz-5.15.0-xxx-generic root/dev/sda2 ro注意vmlinuz版本号要换成你在ls (hd0,gpt2)/boot/里看到的具体文件。如果你不确定根分区是哪个可以先不写root等加载完initrd后看启动报错再调整。紧接着加载内存磁盘镜像initrd /boot/initrd.img-5.15.0-xxx-generic最后启动boot如果一切正常你会看到内核输出滚动然后进入系统登录界面。这里每一步背后都有讲究insmod linux是告诉GRUB怎么解析Linux内核格式linux后面指定的是内核镜像路径和传给内核的启动参数initrd是临时的根文件系统包含加载真正根分区所需的驱动boot才是真正把控制系统交出去。2.3 手动引导阶段最容易踩的三个坑第一个坑是分区号理解错误。(hd0,gpt2)里的hd0是GRUB自己的设备编号不是Linux里的/dev/sda。在多硬盘机器上hd0不一定是对应/dev/sda所以不要凭Linux里的盘序猜GRUB编号老老实实用ls逐个探测。第二个坑是内核和initrd不匹配。如果你ls /boot/里看到好几个vmlinuz和initrd.img一定要选同一版本号的一组。我见过有人图省事linux行用的新版内核initrd行用的旧版镜像结果启动到一半直接kernel panic。第三个坑是根分区参数错误。如果root给错了内核会在挂载根文件系统时失败报出类似Unable to mount root fs的错。这时候不要慌回到grub重新指定正确的根分区就行。在不确定根分区时可以在系统休眠状态下用ls查看各分区的内容特征比如ls (hd0,gpt3)/出现bin、etc、home等目录就说明它是根分区。3. 能进系统之后按这个顺序找根因3.1 第一时间重建GRUB菜单update-grub手动引导进系统只是临时救急如果你什么都不改下次重启大概率还会被丢进grub。第一次登录系统后第一件事是打开终端执行sudo update-grub这条命令会扫描当前系统已安装的内核、其他操作系统的引导信息然后重新生成/boot/grub/grub.cfg。它本质上是grub-mkconfig -o /boot/grub/grub.cfg的封装把缺失的“电话本”重新写出来。绝大多数场景下grub.cfg文件损坏、内容为空、或者上次内核安装中断导致配置没更新一条update-grub就能解决。执行完以后建议再用cat /boot/grub/grub.cfg | grep menuentry看一眼确认菜单项都正常生成。3.2 /boot空间不足与旧内核残留隐蔽的定时炸弹如果你用的Ubuntu把/boot单独划成了一个小分区比如300MB甚至更小那就要格外小心。每次内核升级后系统会尝试在/boot里写入新的vmlinuz和initrd.img文件同时调用update-initramfs更新镜像。如果空间不足内核安装会在半途失败但GRUB可能已经更新了配置指向一个不存在的镜像于是开机直接进grub。排查方法很直接df -h /boot如果Use%超过90%基本就是这个问题。再看一下ls /boot/如果里面堆了七八个旧内核文件就说明清理没跟上。处理办法是让apt自动清理旧内核sudo apt autoremove --purge这条命令会删除已不再需要的旧内核镜像但要注意它不会删掉你当前正在使用的内核。我不建议手动rm /boot/vmlinuz-*因为你可能误删正在用的内核而且手动删除后dpkg的数据库里还有记录下次升级时反而会出乱子。3.3 双系统升级导致Windows“抢”了引导权Windows和Ubuntu双系统用户遇到的grub原因往往不在Ubuntu自己身上而是Windows更新“动了手脚”。Windows大版本更新后有时会重写UEFI的NVRAM启动变量或者把EFI系统分区里的Windows引导文件设为第一优先结果开机要么直接进Windows要么GRUB找不到自己的配置被丢到命令行。这种情况的修复思路不是去Windows里折腾而是从Ubuntu里重装GRUB并把引导顺序改回来。在能进Ubuntu的情况下sudo update-grub sudo grub-installgrub-install会把GRUB重新安装到磁盘的引导区域重写启动项。然后重启按主板快捷键进启动菜单把ubuntu或者带厂商名称的ubuntu条目设为第一启动项。另外提醒一句Windows的“快速启动”功能在UEFI机器上有时会干扰引导流程如果你发现Windows和Ubuntu相互切换总是出问题可以在Windows的电源选项里临时关闭“快速启动”试试。3.4 UUID变化磁盘分区改完之后最常见的失联GRUB配置里的rootUUIDxxxx以及系统里的/etc/fstab都是靠UUID识别分区的。UUID是分区的唯一标识只要分区没被格式化、缩放、复制它不会变。但问题往往出在你自己动过分区。用GParted调整过分区大小、新建过分区、或者做过分区复制之后原分区的UUID可能变了或者分区的顺序发生了变化。这时候GRUB启动时按老UUID找根分区找不到就直接进grub。排查方法是用blkid查看当前各分区的真实UUIDblkid再对照/etc/fstab里的UUID条目cat /etc/fstab如果两者对不上就把/etc/fstab里的UUID改成现在的值。同时别忘了重新生成GRUB配置sudo update-grub因为grub.cfg里的rootUUID也是按老配置生成的不更新的话下次还是会进grub。顺便说一句写/etc/fstab时不要用/dev/sda2这种设备名因为开机时设备名会随硬盘接入顺序变化用UUID才是稳定可靠的。4. BIOS与UEFI模式下永久修复的差别4.1 传统BIOS机器grub-install指向哪个磁盘如果你的机器还是传统BIOS引导也就是用MBR分区表修复GRUB的姿势和UEFI机器完全不同。BIOS机器上主板的固件会直接读取磁盘第一个扇区的引导代码GRUB的第一阶段就写在那里。所以grub-install的目标不是分区而是整块磁盘。假设系统盘是/dev/sda在能进系统的情况下执行sudo grub-install /dev/sda sudo update-grub注意千万别写成grub-install /dev/sda1那样会把GRUB装到分区里而不是MBR里BIOS根本不会去读。多硬盘机器上还有个隐藏问题BIOS启动时可能不是从/dev/sda读取引导而是从另一块盘比如一块旧数据盘。这时候即使你往/dev/sda装了GRUBBIOS还是会从数据盘启动。最简单的验证办法是进BIOS看启动顺序确保排在第一位的是你装GRUB的那块盘。4.2 UEFI机器EFI分区、efibootmgr和Secure BootUEFI机器就不一样了它不读MBR而是从EFI系统分区ESP里读取.efi引导文件。判断当前是UEFI还是BIOS模式可以用ls /sys/firmware/efi如果这个目录存在就是UEFI启动。UEFI模式下修复GRUB的命令是sudo grub-install --targetx86_64-efi --efi-directory/boot/efi --bootloader-idubuntu这里--efi-directory指定EFI分区挂载的位置通常是/boot/efi--bootloader-idubuntu是生成启动项的名字。执行前先确认EFI分区确实挂载了mount | grep /boot/efi如果没挂载先挂载对应的分区。挂载EFI分区要特别注意它通常是FAT32格式不要用chmod乱改权限否则Windows可能识别不了。UEFI模式还有一个经常被忽略的点NVRAM里的启动项。用efibootmgr -v可以查看当前所有的UEFI启动项和顺序。如果列表里没有ubuntu或者顺序不对用下面这个调整sudo efibootmgr -o 0002,0001把ubuntu对应的编号放到第一位。另外如果你之前手动关过Secure Boot建议先恢复开启状态测试一下。Ubuntu一般使用shim签名引导Secure Boot正常情况下是能过的如果开启后进不去说明GRUB安装时用的不是签名版本需要重新安装shim-signed。4.3 为什么很多机器“修完重启又变回grub”这是我在实际维护中遇到最多的反馈Live盘里跑boot-repair明明显示成功了重启之后还是停在grub。拆开看几乎都是这几个原因。第一root分区挂载位置不对。有人在Live环境里把根分区挂到了/mnt但EFI分区挂到了/mnt/boot/efi然后没有正确chroot直接在Live系统里执行grub-install --efi-directory/boot/efi结果写的是Live系统的路径等于没写。第二多硬盘UEFI机器上GRUB被装到了另一块盘的EFI分区。lsblk看一下你的EFI分区到底在哪块盘上再确认grub-install有没有指错。第三NVRAM里的启动项没有变化。grub-install写了文件也生成了启动项但主板固件设置里依然是“直接从硬盘启动”而不是“通过ubuntu引导项”。这种就要进BIOS手动调整启动顺序。第四也是最容易被忽略的Windows更新又把NVRAM改了。你修好了GRUB结果Windows下次大更新又覆盖这是双系统的常态。没有一劳永逸的办法只能养成定期检查启动项的习惯。5. 进不去系统的线下救援Live USB加chroot5.1 制作启动盘并进入试用环境如果连手动引导都搞不定或者根本不知道根分区是怎么回事那就走正规救援路线做一个Ubuntu的Live USB启动盘从U盘启动选择“试用Ubuntu”进入一个临时的桌面系统。在Live环境里你拥有完整的工具链可以挂载原系统磁盘、进入chroot、重新安装GRUB。这个过程不会影响磁盘数据只是借用Live系统的内核和工具来修复磁盘上的原系统。我强烈建议每个Linux用户的抽屉里都放一个这样的Ubuntu启动盘平时看起来没用一旦系统进不去它就是救命稻草。不需要每天更新一台Ubuntu LTS长期支持版本的安装镜像就够用几年。5.2 chroot三步挂载、切换、修引导以下以UEFI机器、根分区是/dev/sda2、EFI分区是/dev/sda1为例。先用lsblk -f确认各分区的设备和文件系统类型。第一步挂载根分区和EFI分区sudo mount /dev/sda2 /mnt sudo mount /dev/sda1 /mnt/boot/efi第二步把Live环境里的系统虚拟文件系统绑到/mnt下这样chroot后的环境才能正常管理进程和网络sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys第三步切进原系统环境执行修复sudo chroot /mnt /bin/bash现在你的终端已经“变成”原系统的根环境直接执行update-grub grub-install --targetx86_64-efi --efi-directory/boot/efi --bootloader-idubuntu完成后退出chrootexit再按顺序卸载分区sudo umount /mnt/sys /mnt/proc /mnt/dev sudo umount /mnt/boot/efi sudo umount /mnt然后重启拔掉U盘看能否正常进系统。如果你用的是LVM逻辑卷挂载前要先激活卷组sudo vgchange -ay否则/dev/sda2对应的逻辑卷路径是不会出现的。我之前帮一位朋友恢复系统时就是漏了这一步折腾了大半天才发现卷组没激活。5.3 懒人方案boot-repair的自动化修复如果你不想手动敲命令boot-repair是这个场景里最常用的图形化工具。在Live环境的终端里执行sudo add-apt-repository ppa:yannubuntu/boot-repair sudo apt update sudo apt install boot-repair启动后点“推荐修复”它会自动做几件事扫描磁盘上的系统、探测已有的GRUB配置、重新安装GRUB到对应位置、重建UEFI启动项最后生成一份修复日志。这个工具适合哪些情况适合你完全确定自己的根分区和EFI分区没被破坏只是引导配置丢了或者启动项乱了。如果磁盘本身挂了、分区表损坏boot-repair也无力回天日志里会清楚地告诉你哪里失败。另外要注意boot-repair在自动修复时可能会改动分区标志修复完成后建议再确认一遍/etc/fstab里有没有设备名依赖。5.4 应急修复工具箱做个简单对比方法适用场景操作难度需要的外部工具grub命令行手动引导GRUB核心能加载配置丢失中无进系统后update-grub能进系统仅配置缺失低无系统内grub-install能进系统引导区域损坏低无Live USB chroot完全无法引导入系统中高启动U盘boot-repair自动修复不熟悉命令行需快速处理低启动U盘和网络我的建议是先根据能否进系统选择大方向能进系统就在系统内修不能进就上Live。命令行能力允许的情况下优先用chroot手动修因为你清楚每一步做了什么出了问题也知道往哪个方向排查。6. 让GRUB以后少出问题的几个现实习惯6.1 内核升级之后不要跳过菜单重建大部分时候Ubuntu在更新内核后会自动调用update-initramfs和update-grub不需要你手动操作。但如果你经常手动管理内核或者不定期清理系统就会打破这个自动流程。我给自己定的习惯是每次apt upgrade完成了内核相关更新后顺手执行一次sudo update-grub哪怕明知道它已经被自动执行过一次。这样做的另一个好处是如果/boot空间不足导致内核安装中断你能在执行update-grub时更早发现异常而不是等重启后才发现进不了系统。防患于未然成本只是一条命令的时间。6.2 双系统安装顺序和升级前的准备Windows和Ubuntu双系统最不容易出问题的安装顺序是先装Windows再装Ubuntu让Ubuntu的安装程序自动识别并添加Windows的引导项。反过来装Windows安装程序往往不客气地重写引导让你只能先进Windows再想办法。Windows大版本更新前如果条件允许建议先在Ubuntu里跑一次sudo update-grub然后备份一下EFI分区的Ubuntu引导文件目录。真被Windows覆盖了你也有备份可以直接恢复。当然最简单粗暴但可靠的办法就是随时备一个Live启动U盘出现问题十分钟内能进chroot修复。6.3 分区调整后严格检查UUID给Linux系统做分区调整无论你用GParted、命令行parted还是Windows的磁盘管理调整完第一件事不是重启而是打开终端执行blkid对比一下/etc/fstab里的UUID有没有变化。很多人在GParted里把根分区往后挪了50GB空间看着很顺利重启就进grub这就是典型的UUID变化问题。如果分区的UUID变了改完/etc/fstab和update-grub后记得再重启验证一次不要觉得改完就万事大吉。6.4 硬件层面的两个小检查软件排查完了还是反复进grub那就该往硬件方向看一眼。最常见的是主板CMOS电池没电导致每次断电后BIOS设置全部重置启动顺序变回默认GRUB启动项排在后面自然进不去。换一颗纽扣电池十几块钱的事却能省下很多莫名其妙的排查时间。另外一个是U盘或移动硬盘插着没拔。有些主板在启动时会优先从可移动设备引导如果你插着一个含有引导文件的U盘就会从一个不该引导的设备启动或者卡在某个不完整的引导环境里。碰到开机进grub先别急着怀疑系统拔掉所有外置存储设备再重启一次有时候问题就消失了。我在实际维护中碰到grub的次数不少但真正需要重装系统的几乎没有。绝大多数时候要么是grub.cfg丢失要么是EFI启动项顺序被改要么是/boot空间不足导致内核更新失败。掌握手动引导那一串命令之后再遇到这种情况就不会慌了。修完之后别忘了做个全盘快照或者至少备份一下/boot/grub/grub.cfg这个文件就是你开机时的那本“电话本”备份好它下次恢复能省一半时间。