update-grub(Grub 2) の grub.cfg に構文エラーがあります (memtest86+)。

update-grub(Grub 2) の grub.cfg に構文エラーがあります (memtest86+)。

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.cfgupdate-grubを実行すると、上記の回避策を含むファイルが作成されます。

背景/追加調査

私のシステム上のフォルダには/etc/grub.d/実際にmemtest86+_proxy:60_memtest86+_proxy62_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

結論として

他の人にはまったく異なる問題があるかもしれません。ただし、少なくとも最初のステップのトラブルシューティングは非常によく似ているはずです。

答え2

@donquixoteの優れたトラブルシューティングステップ(+1賛成)

私の場合、Windows / Ubuntuデュアルブートの並べ替えメニューオプションを設定したときにUbuntuのブート/パーティションを設定しなかったため、エラーが発生しました。

私に役立ったのは、grub-customizerメニューのリストからメニューオプションを上下に移動し、id構文エラーの変更の行番号を観察することでした。これにより、オプションに追加の注意が必要であることがわかります。

答え3

本当に役に立ちました。

私の場合はそのファイルでした/etc/grub.d/proxifiedScripts/custom

grub-customizerルートパスのディレクトリからPrime OSを起動するためのカスタムスクリプトを作成しようとしています。

ファイルを削除し、コマンドがupdate-grubエラーなしで完了し、次のようにカスタムスクリプトを再生成しましたが、grub-customizer正しく実行されました。

答え4

ユーザー、私は一般的なLinux初心者ですが、日が増えるほど強くなっています。私はまだいくつかの新しいコマンドを学んでいますが、すぐにLinuxに慣れるでしょう。

あなたの質問と提供された回答によると、問題が解決されたに違いありませんが、これについてのコメントは引き続き申し上げます。

インターネットの一部のソースによると、以前のKaliカーネルを削除(パージ)するときもこの問題に直面していたため、これらの方法をすべて試しましたが、いずれも私の問題を解決できませんでした。

私は自分のLinuxの知識を使ってジャッピング!解決策が見つかりました。 「update-grub」を実行するたびに、次のような結果が表示されます。 https://im.ge/i/9MH08 それから/boot/grub/grub.cfg.newをチェックしましたが、エラー行は260だったので、まず端末でそれを実行しました。

nano /boot/grub/grub.cfg.new それからCtrl</kbd+Shift</kbd+_間違った行番号を押して入力しました(私は260でした)。

エラーが発生するメニュー項目がありますが、問題が何であるかはわかりません。メニュー項目全体を削除して「update-grub」を実行しましたが、grub 構成ファイルは読み取り専用であるため、変更は適用されませんでした。

もう一度、あなたの投稿によれば、「update-grub」の間、元のgrub.cfgは変更されていませんが、新しいgrub.cfg.newが作成されるため、元のコンテンツを含まないgrub.cfg(読み取り専用です)が表示されます。エラーまたはメニュー項目があるため、すべての行またはエラーに対してこのソリューションは100%動作します。

root 以外の端末ユーザーを起動します。まず実行してsudo suからソリューションに移動します。 rootユーザー:ソリューションに直接移動します。

  1. 次の方法でgrub.cfg.newファイルを削除しました(完全にバックアップではありません)。

    mv /boot/grub/grub.cfg.new /home/grub.cfg.new.bak

  2. その後、元の grub.cfg を grub.cfg.new に置き換えました。

    mv /boot/grub/grub.cfg /boot/grub/grub.cfg.new

新しいエントリが "/home"ディレクトリにバックアップされ、 "/boot/grub/"ディレクトリから削除されたため、古いエントリは新しいエントリに置き換えられます。

  1. その後、端末で「update-grub」を実行し、次のようになります。 https://im.ge/i/9QnRx

誰でもこの簡単なソリューションを試すことができます。

関連情報