报错源于 /etc/default/grub 文件存在非法 shell 语法,如以 2# 开头的行被误解析为命令;修复只需备份后删除非 grub_ 或 # 开头的污染行,并用 grub-mkconfig -o 验证生成成功。

报错直接指向 /etc/default/grub 文件语法错误,不是 GRUB 工具坏了,也不是磁盘或内核问题——修复只需清理这个配置文件里的非法字符,5 分钟内可完成。
报错信息里 “2#: not found” 是什么鬼
这是 shell 解析 /etc/default/grub 时的真实报错:某行开头写了类似 2# 的内容(比如误把注释写成 2# This is a comment),shell 尝试把它当命令执行,结果找不到叫 2# 的可执行文件。
-
Sourcing file `/etc/default/grub`表示 grub-mkconfig 正在用source加载该文件,它必须是合法的 shell 片段 - 报错行号(如
1:)只是大致位置,不一定是第一行;实际出问题的往往是手动编辑时多敲的数字、粘贴进来的乱码、或 IDE 自动补全残留 - 常见污染源:从网页复制配置、用 Windows 编辑器保存(含 BOM)、vim 模式切换失误(比如按了
Ctrl+V后又输数字)、备份脚本误写入
怎么快速定位并清理污染行
别逐行肉眼扫,用 shell 命令直击问题:
- 先看报错是否复现:
source /etc/default/grub—— 如果也报2#: not found,说明文件确实非法 - 查非注释非空行中的异常开头:
grep -n '^[0-9]' /etc/default/grub,会列出所有以数字开头的行(正常配置不应这样) - 检查是否含不可见字符:
cat -A /etc/default/grub | grep '\^M\|@',发现^M(Windows 换行)或@(BOM 标记)就得重存为 Unix 格式 - 安全清理方式:用
sudo cp /etc/default/grub /etc/default/grub.bak备份后,用sudo nano /etc/default/grub打开,删掉所有非GRUB_开头、非#开头的行
grub-mkconfig -o 执行失败的典型连带影响
这个错误看似小,但会阻断所有依赖它的自动化流程:
- 内核升级后,
/etc/kernel/postinst.d/zz-update-grub钩子失败 → 新内核不会出现在 GRUB 菜单 → 重启后还在旧内核上跑,可能缺驱动或补丁 -
update-grub是 Debian/Ubuntu 的封装,本质就是grub-mkconfig -o /boot/grub/grub.cfg,它失败意味着你手动改完GRUB_TIMEOUT也白搭 - 某些 NVIDIA 驱动安装脚本、ZFS 模块更新、甚至
apt autoremove清理旧内核时,都可能触发该钩子 → 错误会静默积累,直到某次重启才爆发 - UEFI 系统下,若
/boot/efi/EFI/ubuntu/grub.cfg是软链到/boot/grub/grub.cfg,这里失败也会导致 EFI 引导项内容陈旧
修复后必须验证的两个动作
改完配置别急着 reboot,两件事没做等于白修:
- 运行
sudo grub-mkconfig -o /boot/grub/grub.cfg,确认输出末尾有Found linux image...且无报错 - 检查生成的
grub.cfg是否真包含新内核:grep -A1 'menuentry.*Linux' /boot/grub/grub.cfg | head -n 10,确保最新vmlinuz版本在列表里 - 如果系统用了独立
/boot分区,记得确认该分区已挂载(mount | grep boot),否则-o会写到根目录下的假路径,看似成功实则无效
最易被忽略的是:很多人修完以为万事大吉,却没意识到 /etc/default/grub 里一个空格、一个制表符、甚至中文全角字符,都可能导致 source 失败——它不像 Python 那样报 SyntaxError,而是直接当命令执行,错误极其隐蔽。











