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.
なぜこれが起こるのですか?どうですか?
背景
Manjaroのアップデート後、システムは起動しなくなりました。 「ファイルが見つかりません」と表示されます/boot/vmlinuz-316-x86_64
。その後、「まずカーネルをロードする必要があります」。
その後、USBスティック(manjaroライブ/インストールプログラムディスク)から起動し、以下の指示に従いました。https://wiki.manjaro.org/index.php/Restore_the_GRUB_Bootloader(UEFIシステム)chrootとupdate-grubを使用してください。実際、「構文エラー」の問題を最初に発見したのは、「EFI変数はこのシステムではサポートされていません」というメッセージを受け取った後にgrubを再インストールしようとすることでした。
私の考えでは(確かではありませんが)このことがしばらく気づかずに進行されたかもしれません。 grub.cfgのすべての更新は失敗しましたが、以前のgrub.cfgはまだ「十分に良好」でした。しかし、更新後にvmlinuzファイルの名前が変更され、grub.cfgは以前に存在しなくなった古いvmlinuzファイルを参照しました。これがスタートアップが失敗した理由だ。
(この記事を書いて、すでに答えを知っています。完全な説明ではないかもしれませんが、修正するだけで十分です。他の人の手間を省くために結果を共有したいと思いました。)
ベストアンサー1
私にとってこれは非常に具体的な答えですが、この問題を解決する方法をより一般的な方法で説明したいと思います。
実際、エラーメッセージにはすでに多くの情報が含まれていますが、最初は明確ではありませんでした。
簡単に言うと:
- /boot/grub/grub.cfg.new の行番号に従ってください。構文エラーが表示される理由を理解してください。
- /etc/default/grubまたは/etc/grub/*の特定のファイルを指すこのファイルの説明に従ってください。
- プロキシスクリプトの場合は、プロンプトに従って検索してください
/etc/grub.d/proxifiedScripts/
。
詳細なトラブルシューティング手順
/boot/grub/grub.cfg
次のファイル数に基づいて、「update-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 ###
空のif/then/fiブロックはシェルスクリプトでは許可されていないため、これは構文エラーです。私の考えでは、これは非常に愚かな言語設計ですが、実際にはそうです。
また、ブロックに不可解な説明を追加して修正を見つけました。 Colonをお勧めしますが、他の回避策があるかもしれません。
### BEGIN /etc/grub.d/60_memtest86+_proxy ###
if [ "${grub_platform}" == "pc" ]; then
:
fi
### END /etc/grub.d/60_memtest86+_proxy ###
より良いアプローチは、この意味のないブロックを完全に削除することです。
これで、次の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~
"
/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
[..]
ファイル自体はシェルスクリプトですが、「cat」文があります。これらの印刷シェルスクリプトの一部は/boot/grub/grub.cfg
少し変更され、最終的には機能します。
では、/boot/grub/grub.cfg.new
「menuentry...」の内容が実際に失われ、代わりに空のthen..fiブロックを取得することを観察します。なぜ「メニュー項目…」が消えたのかわかりません。たぶん、グラブはそれが必要だとは思わないかもしれません。残念ながら、削除によりスクリプトが破損しています。
解決策
トリック/解決方法は、次のようにこのファイルにコロンを追加することです。
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}
}
grub.cfg
update-grubを実行すると、上記の回避策を含むファイルが作成されます。
背景/追加調査
私のシステム上のフォルダには/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
したがって、両方のファイルは同じプロキシスクリプトを参照しますが、結果は異なるパラメータを使用してgrubcfg_proxyバイナリを介してパイプされます。これらの様々なパラメータが60_memtest86+_proxy
。
結論として
他の人にはまったく異なる問題があるかもしれません。ただし、少なくとも最初のステップのトラブルシューティングは非常によく似ているはずです。