Regenerate GRUB Safely with update-grub
Change one line in /etc/default/grub, forget to regenerate, and your setting does nothing at the next boot: that is what update-grub is for. On this machine it comes from grub2-common version 2.12-1ubuntu7.3, and it is a thin wrapper around grub-mkconfig, not a menu editor.
The route
Jump straight to the step you need, or tick off Done means at the end.
You will regenerate /boot/grub/grub.cfg, confirm the new file actually landed, and know where to look when generation fails. Allow about ten minutes, plus time to review whatever boot setting you are changing.
- An administrator shell and a working GRUB installation.
- Recovery access (console or rescue boot) before you touch anything, since this changes what the next boot reads.
1. Check the setting before regenerating
GRUB reads its main config from /etc/default/grub, then fragments from /etc/default/grub.d/, then runs the executable scripts in /etc/grub.d/. Look at all three before changing anything:
$ sudo sed -n '1,220p' /etc/default/grub
$ sudo find /etc/default/grub.d -maxdepth 1 -type f -name '*.cfg' -print 2>/dev/null
$ sudo find /etc/grub.d -maxdepth 1 -type f -perm /111 -printf '%f\n' | sort
Use sudo if your account cannot read these files.
Warning
Never edit /boot/grub/grub.cfg by hand. It is generated output and the next update overwrites it.
Checkpoint
Write down the exact file and setting you intend to change. If you have not changed a setting or installed a kernel, stop here: there is nothing to regenerate.
2. Make one controlled configuration change
For something like a menu timeout, edit the existing setting in /etc/default/grub with an editor you trust:
$ sudoedit /etc/default/grub
- Keep it valid POSIX shell. The file is sourced as shell code during generation, so a simple assignment like
GRUB_TIMEOUT=5is safe, but never paste untrusted text into it. - Quote values with spaces or shell punctuation. An unquoted value can break parsing in ways that are hard to spot later.
Back the file up first so an undo is one command away:
$ sudo cp -p /etc/default/grub /etc/default/grub.backup-before-grub-update
To undo before regenerating, restore that copy and check it:
$ sudo cp -p /etc/default/grub.backup-before-grub-update /etc/default/grub
$ sudo sh -n /etc/default/grub
Tip
The shell syntax check only confirms the file parses. It says nothing about whether a GRUB variable does what you intended.
3. Regenerate the GRUB configuration
Run the wrapper as root:
$ sudo update-grub
Sourcing file `/etc/default/grub'`
Generating grub configuration file ...
done
The exact source-file lines vary with whatever fragments and scripts you have installed. What matters is a clean exit and the final done. Under the hood the wrapper runs grub-mkconfig -o /boot/grub/grub.cfg, so no output filename is needed, and update-grub2 is just an alias for the same command on this system.
Warning
This replaces the configuration used at the next boot. It does not install a bootloader into firmware and it will not repair a broken one. A bad setting can now surface at reboot, so do not reboot until the verification step below passes.
4. Verify the generated file
In a script or automation, check the exit status straight away:
$ sudo update-grub
$ status=$?
$ printf 'update-grub exit status: %s\n' "$status"
update-grub exit status: 0
Then confirm the target exists, belongs to root, and holds generated content:
$ sudo stat -c '%U %G %a %s %n' /boot/grub/grub.cfg
root root 600 12345 /boot/grub/grub.cfg
$ sudo sed -n '1,16p' /boot/grub/grub.cfg
The size shown is only an example; yours will differ. The opening comments should say the file is automatically generated. A plausible file size is not proof every menu entry you expected is present, so search for a specific one when you have one in mind:
$ sudo grep -nF 'menuentry' /boot/grub/grub.cfg | head
5. Diagnose a failed update without guessing
If the command exits non-zero, read the error before retrying rather than running it again and hoping. A syntax error in /etc/default/grub or in an executable script under /etc/grub.d/ can stop generation cold:
$ sudo sh -n /etc/default/grub
$ sudo ls -l /etc/grub.d
$ sudo find /etc/default/grub.d -maxdepth 1 -type f -name '*.cfg' -exec sh -n '{}' \;
Generation writes to a temporary file beside the target and validates it before installing it. A failed run is never permission to hand-edit the existing grub.cfg: fix the reported source file, re-run the checks, then regenerate.
For a harmless capability check that exits before any generation happens:
$ grub-mkconfig --help
Usage: grub-mkconfig [OPTION]
Generate a grub config file
Warning
Do not use grub-mkconfig --output=/tmp/test.cfg as a stand-in for the real update. A different output path still runs every discovery script, and it may not reproduce your machine's normal boot configuration context.
6. Recover from an unwanted change
If you have not rebooted yet, the previous boot configuration may still sit in your backups or a package-managed recovery process. Restore whatever caused the problem, then regenerate. Using the example backup from earlier:
$ sudo cp -p /etc/default/grub.backup-before-grub-update /etc/default/grub
$ sudo sh -n /etc/default/grub
$ sudo update-grub
Recovery
If the machine already will not boot, use the provider's console or a trusted recovery environment. Mount the installed system, repair /etc/default/grub or the offending /etc/grub.d/ file, then chroot in and follow your distribution's documented recovery procedure. Do not delete /boot/grub/grub.cfg as a first response.
Done means
- The intended setting is confirmed. It is present in the source file, which passes a shell syntax check.
- The regeneration succeeded.
sudo update-grubexited 0 and reported completion. - The output file checks out.
/boot/grub/grub.cfgexists and shows the generated-file comment header. - A known entry is present. When you expected a specific menu entry, you found it.
- You have not rebooted blind. The generated result is understood and recovery access is ready before you reboot.