The GRUB 'grubenv' Variable

I'm working my way through the basics of GRUB's DSL. Much of this stuff is - like so many things in Linux - obvious once you know it. But incredibly opaque until you do. I haven't found a good GRUB DSL tutorial, so maybe this can fill that void.

When you create GRUB bootable media, one of the files dropped in is /boot/grub/grubenv (or /boot/grub2/grubenv if you're using Fedora). This appears to be a simple text file. It can be shown with cat /boot/grub/grubenv from the GRUB command line (assuming your '$root' variable is still set to the default drive), but it can also be manipulated by a couple GRUB commands to interesting effect.

grub> set color_normal=green/black

This command will change the colours you see in GRUB from the default light gray on black to green on black (color_normal is a GRUB "Special Environment Variable").

grub> save_env color_normal
grub> reboot

The system will reboot. But this is where it gets interesting.

grub> load_env color_normal
grub>

This will pull the saved setting from the /boot/grub/grubenv file and change the colour of your GRUB terminal.

I read somewhere that this setting doesn't work on USB. This appears to be incorrect as I'm doing all my testing on a USB stick with GRUB installed, and it works fine.

The most obvious use for this would probably be to save your previous OS boot choice as the default for the next boot. Other possible uses would include saving colour, font, or background picture choices from one boot to the next.

Here's a very basic implementation with a GRUB submenu. If you choose one of the last three entries, it changes the colours and saves the setting. If you choose the first entry, it reloads the last saved entry (including on another machine because it's stored on the USB stick).

submenu "Ugly Colours and Environment Settings" {

    menuentry "Load previous colour choices" {
        load_env color_normal
        load_env color_highlight
    }

    menuentry "light-gray/black and white/dark-grey" {
        set color_normal=light-gray/black
        set color_highlight=white/dark-grey
        save_env color_normal
        save_env color_highlight
    }

    menuentry "yellow/blue and light-blue/brown" {
        set color_normal=yellow/blue
        set color_highlight=light-blue/brown
        save_env color_normal
        save_env color_highlight
    }

    menuentry "white/green and green/black" {
        set color_normal=white/green
        set color_highlight=green/black
        save_env color_normal
        save_env color_highlight
    }
}

The contents of the grubenv file now look like this:

# GRUB Environment Block
color_normal=white/green
color_highlight=green/black
##################################################### ...

That's not a literal space and three periods at the end - there's a single line of 947 hash marks (confirmed by piping to wc -c) that I'm not going to show here.