当我运行 update-grub 或尝试重新安装它时,出现“语法错误”。
输出有点像这样:
error: syntax error.
error: Incorrect command.
error: syntax error.
error: line no: 262
Syntax errors are detected in generated GRUB config file.
Ensure that there are no errors in /etc/default/grub
and /etc/grub.d/* files or please file a bug report with
/boot/grub/grub.cfg.new file attached.
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我能做什么?
在 Manjaro 更新后,我的系统不再启动。它说“/boot/vmlinuz-316-x86_64
找不到文件”。然后“您需要先加载内核”。
然后我从 USB 记忆棒(manjaro live/安装程序磁盘)启动,并按照https://wiki.manjaro.org/index.php/Restore_the_GRUB_Bootloader(UEFI系统)中的说明使用 chroot 和 update-grub。事实上,在我尝试重新安装 grub 的步骤中,我首先注意到“语法错误”问题,因为我收到“此系统不支持 EFI 变量”。
我想(但不确定)这可能已经持续了一段时间而没有引起注意。对 grub.cfg 的任何更新都失败了,但旧的 grub.cfg 仍然“足够好”。但是随着更新,vmlinuz 文件被重命名,grub.cfg 引用了一个旧的,不再存在的 vmlinuz 文件。这就是启动失败的原因。
(我在写这篇的时候已经知道答案了。可能解释不完整,但我修复它已经足够了。我只是想分享结果,省去别人的麻烦)
对我来说,这是一个非常具体的答案,但我想以更一般的方式解释如何解决这个问题。
实际上很多信息已经在错误消息中了,但对我来说一开始并不明显。
简而言之:
/etc/grub.d/proxifiedScripts/
.该/boot/grub/grub.cfg
是在“更新grub的”自动创建的,基于大量的文件:/etc/default/grub
和中的任何文件/etc/grub.d/*
。
/boot/grub/grub.cfg.new
但是,如果出现语法错误(或任何错误,我想),原始/boot/grub/grub.cfg
文件不会被覆盖,而是在/boot/grub/grub.cfg.new
.
错误消息包含一个行号,在我的例子中是 262,它指的是这个/boot/grub/grub.cfg.new
文件。就我而言,这是 262。查看文件,我发现:
### BEGIN /etc/grub.d/60_memtest86+_proxy ###
if [ "${grub_platform}" == "pc" ]; then
fi
### END /etc/grub.d/60_memtest86+_proxy ###
Run Code Online (Sandbox Code Playgroud)
我了解到不允许在 shell 脚本中使用空的 if/then/fi 块,所以这是语法错误。很愚蠢的语言设计imo,但事实就是这样。
我还找到了一个修复方法,就是在块中添加一个无意义的语句。建议使用冒号,但可能还有其他解决方案。
### BEGIN /etc/grub.d/60_memtest86+_proxy ###
if [ "${grub_platform}" == "pc" ]; then
:
fi
### END /etc/grub.d/60_memtest86+_proxy ###
Run Code Online (Sandbox Code Playgroud)
更好的是完全删除这个无意义的块。
现在我们真的不想手动编辑这个文件,因为更改将在下一次 update-grub 中被擦除(如果成功,这就是目标)。
/etc/grub.d/*
代码片段包含下一步要查看的提示:/etc/grub.d/60_memtest86+_proxy
. 这个文件说:
#!/bin/sh
#THIS IS A GRUB PROXY SCRIPT
'/etc/grub.d/proxifiedScripts/memtest86+' | /etc/grub.d/bin/grubcfg_proxy "+*
+#text
-'Memory Tester (memtest86+)'~30b99791e52c3f0cb32601c5b8f57cc7~
"
Run Code Online (Sandbox Code Playgroud)
/etc/grub.d/proxifiedScripts/*
的相关部分/etc/grub.d/proxifiedScripts/memtest86+
是这样的:
[..]
cat << EOF
if [ "\${grub_platform}" == "pc" ]; then
menuentry "Memory Tester (memtest86+)" ${CLASS} {
search --fs-uuid --no-floppy --set=root ${_GRUB_MEMTEST_HINTS_STRING} ${_GRUB_MEMTEST_FS_UUID}
linux16 ${_GRUB_MEMTEST_REL_PATH} ${GRUB_CMDLINE_MEMTEST86}
}
fi
EOF
[..]
Run Code Online (Sandbox Code Playgroud)
该文件本身是一个 shell 脚本,但它有那些“cat”语句。这些打印最终应该进入的 shell 脚本片段/boot/grub/grub.cfg
。经过一些修改,也许。
在 中/boot/grub/grub.cfg.new
,我们观察到“menuentry ...”的东西实际上丢失了,取而代之的是一个空的 then..fi 块。为什么“menuentry ...”消失了,我不知道。也许 grub 认为不需要它。不幸的是,删除破坏了脚本。
技巧/解决方法是在此文件中添加一个冒号,如下所示:
if [ "\${grub_platform}" == "pc" ]; then
:
menuentry "Memory Tester (memtest86+)" ${CLASS} {
search --fs-uuid --no-floppy --set=root ${_GRUB_MEMTEST_HINTS_STRING} ${_GRUB_MEMTEST_FS_UUID}
linux16 ${_GRUB_MEMTEST_REL_PATH} ${GRUB_CMDLINE_MEMTEST86}
}
Run Code Online (Sandbox Code Playgroud)
运行 update-grub 时,这会生成grub.cfg
具有上述解决方法的 。
/etc/grub.d/
我系统上的文件夹实际上包含 memtest86+_proxy:60_memtest86+_proxy
和62_memtest86+_proxy
. 我认为其中一个是某种剩余物。但是它们都有相同的更新时间戳,所以我真的不知道删除哪个可以安全。差异显示了这一点:
--- /etc/grub.d/60_memtest86+_proxy 2015-01-08 15:54:02.228927526 +0100
+++ /etc/grub.d/62_memtest86+_proxy 2015-01-08 15:54:02.228927526 +0100
@@ -1,6 +1,6 @@
#!/bin/sh
#THIS IS A GRUB PROXY SCRIPT
-'/etc/grub.d/proxifiedScripts/memtest86+' | /etc/grub.d/bin/grubcfg_proxy "+*
-+#text
--'Memory Tester (memtest86+)'~30b99791e52c3f0cb32601c5b8f57cc7~
+'/etc/grub.d/proxifiedScripts/memtest86+' | /etc/grub.d/bin/grubcfg_proxy "+'Memory Tester (memtest86+)'~30b99791e52c3f0cb32601c5b8f57cc7~
+-*
+-#text
"
\ No newline at end of file
Run Code Online (Sandbox Code Playgroud)
因此,这两个文件都引用了相同的代理脚本,但结果是通过 grubcfg_proxy 二进制文件通过管道传输的,具有不同的参数。这些不同的参数可能负责在60_memtest86+_proxy
.
其他人可能有完全不同的问题。但是故障排除,至少是第一步,应该非常相似。
归档时间: |
|
查看次数: |
11092 次 |
最近记录: |