Skip to main content
added 346 characters in body
Source Link
donquixote
  • 1.8k
  • 3
  • 15
  • 18

In short:

  • Follow the line number, in /boot/grub/grub.cfg.new. Try to understand why what you find there is a syntax error.
  • Follow the comment in this file, that points to either /etc/default/grub, or a specific file in /etc/grub/*.
  • In case of a proxy script, follow the hint to a file in /etc/grub.d/proxifiedScripts/.

Troubleshooting steps, in detail

Troubleshooting steps

In short:

  • Follow the line number, in /boot/grub/grub.cfg.new. Try to understand why what you find there is a syntax error.
  • Follow the comment in this file, that points to either /etc/default/grub, or a specific file in /etc/grub/*.
  • In case of a proxy script, follow the hint to a file in /etc/grub.d/proxifiedScripts/.

Troubleshooting steps, in detail

Source Link
donquixote
  • 1.8k
  • 3
  • 15
  • 18

For me it was a very specific answer, but I want to explain in a more general way how to troubleshoot this.

Actually a lot of the information is already in the error message, but to me it was not obvious at first.

Troubleshooting steps

The /boot/grub/grub.cfg is automatically created on "update-grub", based on a number of files: /etc/default/grub, and any files in /etc/grub.d/*.

/boot/grub/grub.cfg.new
However, in case of a syntax error (or any error, I suppose), the original /boot/grub/grub.cfg is NOT overwritten, but instead the new file is created in /boot/grub/grub.cfg.new.

The error message contains a line number, in my case 262, that refers to this /boot/grub/grub.cfg.new file. In my case, this was 262. Looking at the file, I found this:

### BEGIN /etc/grub.d/60_memtest86+_proxy ### if [ "${grub_platform}" == "pc" ]; then fi ### END /etc/grub.d/60_memtest86+_proxy ### 

I learned that en empty if/then/fi block in shell script is not allowed, so this was the syntax error. Quite stupid language design imo, but this is how it is.

I also found a fix, which is to add a meaningless statement in the block. A colon was suggested, but there might be other solutions.

### BEGIN /etc/grub.d/60_memtest86+_proxy ### if [ "${grub_platform}" == "pc" ]; then : fi ### END /etc/grub.d/60_memtest86+_proxy ### 

Even better would be to remove this meaningless block completely.

Now we don't really want to edit this file manually, because the changes would be wiped on the next update-grub (if successful, which is the goal).

/etc/grub.d/*
The snippet contains a hint where to look next: /etc/grub.d/60_memtest86+_proxy. This file says:

#!/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/*
The relevant part of /etc/grub.d/proxifiedScripts/memtest86+ is this:

 [..] 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 [..] 

The file itself is a shell script, but then it has those "cat" statements. These print the shell script snippets that should finally go into /boot/grub/grub.cfg. With some modifications, maybe.

In the /boot/grub/grub.cfg.new, we observe that the "menuentry ..." stuff is actually missing, and instead we get an empty then..fi block. Why the "menuentry ..." disappears, I don't know. Maybe grub thinks that it is not needed. Unfortunately, the removal breaks the script.

Workaround

The trick / workaround was to add a colon in this file, like this:

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} } 

When running update-grub, this generates a grub.cfg with the workaround described above.

Background / More investigation

The /etc/grub.d/ folder on my system actually contained two files for memtest86+_proxy: 60_memtest86+_proxy and 62_memtest86+_proxy. I assume that one of them is a leftover of some sort. But both of them have the same updated timestamp, so I really don't know which of them would be safe to delete. A diff shows this:

--- /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 

So, both of the files refer to the same proxified script, but the result is piped through the grubcfg_proxy binary, with different parameters. These different parameters could be responsible for removing the "menuentry ..." stuff in case of the 60_memtest86+_proxy.

Conclusion

Others may have completely different problems. But the troubleshooting, at least the first steps, should be quite similar.