Regenerate the GRUB Menu Safely with grub-mkconfig
Running grub-mkconfig straight at /boot/grub/grub.cfg and hoping is how people end up staring at a rescue shell. Generate into a temporary file first, inspect it, then install it at the location your machine actually uses. Allow 10 to 20 minutes including a reboot-free verification.
The route
Jump straight to the step you need, or tick off Done means at the end.
The examples target the installed grub-common package, version 2.12-1ubuntu7.3, on this machine.
1. Check the installed command
grub-mkconfig assembles a configuration from the settings in /etc/default/grub and the executable scripts in /etc/grub.d. By default it writes the generated text to standard output, or to a file if you pass -o. It does not install GRUB or pick a disk for you.
$ grub-mkconfig --version
grub-mkconfig (GRUB) 2.12-1ubuntu7.3
$ grub-mkconfig --help
Usage: grub-mkconfig [OPTION]
Generate a grub config file
This installed version documents exactly three options: --output=FILE, --help and --version. Do not carry over an option from a different GRUB tool.
2. Inspect the inputs before changing anything
Read the current settings and list the generator scripts. Both are ordinary, unprivileged reads on a typical install:
$ sed -n '1,220p' /etc/default/grub
$ find /etc/grub.d -maxdepth 1 -type f -printf '%f %m\n' | sort
- Values in /etc/default/grub are sourced as POSIX shell. Keep assignments valid shell syntax and quote anything with spaces or metacharacters.
- Scripts in /etc/grub.d run if their executable bit is set. Never paste an untrusted file into either location: changing these inputs changes what lands in the next boot configuration.
Checkpoint
If you just changed a setting, record the old line or take a backup before proceeding. This creates a dated copy without touching the live file:
$ sudo cp --preserve=all /etc/default/grub /etc/default/grub.before-$(date +%Y%m%d-%H%M%S)
That is the first command in this guide that normally needs elevated privileges.
3. Generate a disposable configuration first
Write to a path in /tmp for the first run. The output file is disposable and the command never touches /boot/grub/grub.cfg on its own:
$ test -d /tmp/grub-check || mkdir /tmp/grub-check
$ sudo grub-mkconfig --output=/tmp/grub-check/grub.cfg
Generating grub configuration file ...
done
The exact messages depend on your generator scripts, so lean on the exit status rather than matching a particular line:
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ test -s /tmp/grub-check/grub.cfg && echo 'generated file is non-empty'
generated file is non-empty
Example
On this machine, running the command without elevated privileges stops with grub-mkconfig: You must run this as root. That is a permission check, not a reason to make the output file world-writable.
4. Inspect the generated entries
Look at the parts that matter for your change: the file header, menu entries, kernel paths, root identifiers, any custom entries. This is read-only inspection:
$ sed -n '1,100p' /tmp/grub-check/grub.cfg
$ grep -nE '^(menuentry|submenu|linux|initrd|search)' /tmp/grub-check/grub.cfg
A non-empty file is not proof every entry is correct. The generator can finish clean while a kernel, chainloader or custom script silently drops the entry you expected. Compare the result against /boot and against the change you intended, and fix any custom script that prints sensitive data or shell errors before you install its output.
For a custom menu item, the usual extension points are /etc/grub.d/40_custom or /boot/grub/custom.cfg, depending on your distribution's layout. Keep the first lines of 40_custom intact, and test a custom entry's paths and recovery route before relying on it: it can be boot-critical.
5. Install the generated configuration
Warning
Replacing the active GRUB configuration changes the next boot. A malformed or incomplete file can leave the machine unable to reach its normal menu. Keep the previous file until the new one is tested, and arrange physical or console access before doing this on a remote host.
Identify the configuration path your installation actually uses. A conventional Ubuntu layout puts it at /boot/grub/grub.cfg, but do not assume that for every platform:
$ sudo grub-mkconfig --output=/boot/grub/grub.cfg
Generating grub configuration file ...
done
Check the exit status, then the resulting file:
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sudo test -s /boot/grub/grub.cfg && echo 'installed file is non-empty'
installed file is non-empty
This command only generates the configuration, it does not run grub-install. Do not follow it with grub-install unless you have a separate, verified reason to install or repair the bootloader itself.
6. Recover from a bad result
If generation fails, the output path may be empty or incomplete. Do not reboot to see what happens. Check the error text, the syntax of /etc/default/grub, permissions on the generator scripts, and any script named in the diagnostic:
$ sudo sh -n /etc/default/grub
$ find /etc/grub.d -maxdepth 1 -type f -executable -print | sort
Recovery
If you already replaced the active file and need it back, restore from a backup made before the change, confirming first that it exists and is a regular file:
$ sudo test -f /boot/grub/grub.cfg.before-change && \
sudo cp --preserve=all /boot/grub/grub.cfg.before-change /boot/grub/grub.cfg
That restore changes boot configuration again, so check its exit status and keep console access available. With no known-good backup, stop changing files and use your distribution's documented boot-repair procedure from local or rescue media.
Done means
- Version checked. The installed GRUB version and package were confirmed.
- Inputs reviewed.
/etc/default/gruband the executable generator scripts were checked. - Disposable run first. A test configuration was generated and inspected before anything live changed.
- Entries checked. The active configuration was only replaced after reviewing entries and confirming machine access.
- Recovery ready. The generated file is non-empty, the command returned status 0, and a recovery copy or rescue route exists.