67

I have a dual boot Linux/windows system set up, and frequently switch from one to the other. I was thinking if I could add a menu item in one of the menus to reboot directly into windows, without stopping at the GRUB prompt.

I saw this question on a forum, that's exactly what I want but it's dealing with lilo, which is not my case.

I thought of a solution that would modify the default entry in the GRUB menu and then reboot, but there are some drawbacks, and I was wondering if there was a cleaner alternative.

(Also, I would be interested in a solution to boot from Windows directly into Linux, but that might be harder, and does not belong here. Anyway, as long as I have it in one way, the other way could be set up as the default.

UPDATE It seems someone asked a similar question, and if those are the suggested answers, I might as well edit /boot/grub/grubenv as grub-reboot and grub-set-default and grub-editenv do. )

Thanks in advance for any tips.

UPDATE:

This is my GRUB version: (GRUB) 1.99-12ubuntu5-1linuxmint1

I tried running grubonce, the command is not found. And searching for it in the repositories gives me nothing. I'm on Linux Mint, so that might be it...

Seeing man grub-reboot, it seems like it does what I want, as grubonce does. It is also available everywhere (at least it is for me, I think it is part of the grub package). I saw two related commands: grub-editenv and grub-set-default.

I found out that after running sudo grub-set-default 4, when running grub-editenv list you get something similar to:

saved_entry=4

And when running grub-reboot 4, you get something like:

prev_saved_entry=0
saved_entry=4

Which means both do the same thing (one is temporary one is not).

Surprisingly, when I tried:

sudo grub-reboot 4
sudo reboot now

It did not work, as if I hadn't done anything, it just showed me the menu as usual, and selected the first entry, saying it will boot this entry in 10s.

I tried it again, I thought I might have written the wrong entry (it is zero-based, right?). That time, it just hanged at the menu screen, and I had to hard-reset the PC to be able to boot.

If anyone can try this out, just to see if it's just me, I'd appreciate it. (mint has been giving me a hard time, and that would be a good occasion to change :P).

Reading the code in /boot/grub/grub.cfg, seems like this is the way to go, but from my observations, it's just ignoring these settings...

1
  • what distro are you on? I think i've got it working on my Debian.
    – jw013
    Commented Jul 16, 2012 at 22:14

13 Answers 13

57
  1. Edit the /etc/default/grub and replace GRUB_DEFAULT=0 with GRUB_DEFAULT=saved
  2. sudo update-grub
  3. Your command will be:

    sudo grub-reboot "$(grep -i windows /boot/grub/grub.cfg|cut -d"'" -f2)" && sudo reboot
    

    A pretty function for your ~/.bashrc or .bash_aliases could look like:

    # Reboot directly to Windows
    # Inspired by http://askubuntu.com/questions/18170/how-to-reboot-into-windows-from-ubuntu
    reboot_to_windows ()
    {
        windows_title=$(grep -i windows /boot/grub/grub.cfg | cut -d "'" -f 2)
        sudo grub-reboot "$windows_title" && sudo reboot
    }
    alias reboot-to-windows='reboot_to_windows'
    

    Editor's notes:

    • I have replaced deprecated backticks (``) by $(...) construct.

    • In general, I have re-written it to adhere to current POSIX (wiki) standards, and while at it, did a few minor other changes.

    • For completeness, I left the below function untouched for comparison.


In case, your grub.conf contains multiple lines for Windows, following functions will take care only about lines starting by menuentry and picking just the first one, referring to Windows:

function my_reboot_to_windows {
    WINDOWS_TITLE=`grep -i "^menuentry 'Windows" /boot/grub/grub.cfg|head -n 1|cut -d"'" -f2`
    sudo grub-reboot "$WINDOWS_TITLE"
    sudo reboot
}
3
  • 1
    My file /boot/grub/grub.cfg contains more lines with "Windows" in it, many of them stating something like ...=1 i915.semaphores=1 acpi_osi='!Windows 2012' $vt..., so I assume your code would fail on it. This can be fixed by grepping for ^menuentry 'Windows. Commented Jan 13, 2015 at 16:11
  • 2
    This should be marked as the correct answer. Commented Apr 14, 2016 at 19:46
  • The function is more helpful than I thought.
    – Carson Ip
    Commented Apr 21, 2017 at 12:30
32

In order for the grub-reboot command to work, several required configuration changes must be in place:

  • The default entry for grub must be set to saved. One possible location for this is the GRUB_DEFAULT= line in /etc/default/grub
  • Use grub-set-default to set your default entry to the one you normally use.
  • Update your grub config (e.g. update-grub).

This should take care of the initial set-up. In the future, just do grub-reboot <entry> for a one-time boot of <entry>.

7
  • 1
    I see ur words "default entry for grub must be set to saved", while my keeping GRUB_DEFAULT=0 also sufficed. So is saved unnecessary? Commented Aug 12, 2016 at 7:58
  • Im not sure if everyone realizes how cool this feature really is, I plan to boot win7ult64 with rhel64, and vice versa, whilst having the rhel become auto available for another win networked systems scheduled backup task, which pushes to the rhel zfs raidz2. Then at backup complete, the grubbed system auto boots back into a windows gamer iis server playground for the rest of the week, rinse and repeat. Its a shape shifter. :-) Commented Jan 26, 2017 at 10:18
  • It took me ages to notice that grub-reboot fails silently, giving a success return code. I hope my suggested edit is ok. :-)
    – Nobody
    Commented Apr 21, 2017 at 13:06
  • That doesn't appear to be the case anymore, at the very least in Debian Buster grub version neither running update-grub nor having default set to saved was necessary, grub-reboot <entry> was all that was needed for me
    – XANi
    Commented Apr 7, 2021 at 18:56
  • 1
    @RokeJulianLockhart docs.fedoraproject.org/en-US/fedora/latest/… suggests it might be called grub2-set-default now. This answer is over a decade old, I can't vouch for it anymore and don't really have the time to update it, so I would recommend checking more recent sources where possible.
    – jw013
    Commented Jun 24 at 12:55
4

I've written a tool to do this for Ubuntu 20.04/22.04: https://github.com/mendhak/grub-reboot-picker

enter image description here

It might work on previous Ubuntus but I've never tested it.

2

I use openSUSE which comes with a script called grubonce, which does exactly what you need - set grub entry to be used on next reboot.

# grubonce
0: Trace -- openSUSE 12.1 - 3.1.10-1.16
1: Debug -- openSUSE 12.1 - 3.1.10-1.16
2: Desktop -- openSUSE 12.1 - 3.1.10-1.16
3: Failsafe -- openSUSE 12.1 - 3.1.10-1.16

# grubonce 0
Using entry #0: Trace -- openSUSE 12.1 - 3.1.10-1.16

# grubonce 2
Using entry #2: Desktop -- openSUSE 12.1 - 3.1.10-1.16

I don't know which (if any) other distributions ship this script, so in case your distro does not have it, you can check out this page:

http://sidvind.com/wiki/GRUB:_Boot_another_OS_once

1
  • Its actually part of grub and trustedgrub (whatever that is) and NOT grub2 so I do not have it installed on tumbleweed june 2019 Commented Jun 26, 2019 at 7:07
2

Agree with @jw013. And you can also give the menu tile to grub-reboot (including the title of parent menu). e.g:

$ sudo grub-reboot "Advanced options for Ubuntu>Ubuntu, with Linux 4.13.0-26-generic"
$ sudo reboot

Where "Advanced options for Ubuntu" is the parent menu, "Ubuntu, with Linux 4.13.0-26-generic" is submenu.

1
  • sudo grub-reboot '0>3' or sudo grub-reboot '1>3' did not work but sudo grub-reboot 'Advanced options for Ubuntu>Ubuntu, with Linux 4.4.0-179-generic' did. Thank you. Commented Jun 10, 2020 at 19:29
2

As of Fedora 30, Roy's answer doesn't work anymore. Fedora entries are not listed as menuentry in grub.cfg and instead are taken from files in /boot/loader/entries. You can either lookup the entries with grubby --info=ALL or take the number of files in /boot/loader/entries.

Reddit thread Fedora Docs Boot Loader Specs

Here the modified script below (Fedora 30 and higher):

#!/bin/bash
if [ `readlink /boot/grub2/grubenv` == "/boot/efi/EFI/fedora/grubenv" ]; then
    sudo mv /boot/grub2/grubenv /boot/grub2/grubenv-original
    sudo ln -s ../efi/EFI/fedora/grubenv /boot/grub2/grubenv
fi
MENU_ENTRY=`grep ^menuentry /boot/efi/EFI/fedora/grub.cfg  | grep --line-number Windows`
FEDORA_ENTRIES=`grubby --info=ALL | grep index | wc -l`
#FEDORA_ENTRIES=`ls -1 /boot/loader/entries | wc -l`
MENU_NUMBER=$(( `echo $MENU_ENTRY | sed -e "s/:.*//"` + `echo $FEDORA_ENTRIES` - 1))
sudo grub2-reboot $MENU_NUMBER
sudo reboot
1

grub-set-default seems more available (grubonce isn't listed in Ubuntu 'verse). It may also be more helpful as Windows 7 has a habit of performing a reboot during startup if updates were applied at last shutdown (that is, it begins startup, processes some update data, reboots, and then displays login page).
I've often started Windows 7 only to come back and find Ubuntu running.

1
  • 1
    I turned off Windows update, so that should not be a problem :D, I'll try this. From what I saw, it seems like this does the same thing as grub-reboot. I'm editing my question with more detail. Thanks anyway.
    – jadkik94
    Commented Jul 16, 2012 at 20:52
1

In Fedora, you can use the following script. Note that this is mostly the same as described in https://askubuntu.com/a/18186/149422, with a few modifications for GRUB 2 in Fedora.

#!/bin/bash
if [ `readlink /boot/grub2/grubenv` == "/boot/efi/EFI/fedora/grubenv" ]; then
    sudo mv /boot/grub2/grubenv /boot/grub2/grubenv-original
    sudo ln -s ../efi/EFI/fedora/grubenv /boot/grub2/grubenv
fi
MENU_ENTRY=`grep ^menuentry /boot/grub2/grub.cfg  | grep --line-number Windows`
MENU_NUMBER=$(( `echo $MENU_ENTRY | sed -e "s/:.*//"` - 1 ))
sudo grub2-reboot $MENU_NUMBER
sudo reboot
1

I am using Ubuntu 16.04 and the above solutions did not work for me ... for some reason sudo grub-reboot 2 never seemed to update the /boot/grub/grubenv file, even after changing GRUB_DEFAULT=0 to GRUB_DEFAULT=saved in both /etc/default/grub and /boot/grub/menu.lst. Using the savedefault --default=2 --once command in grub also did not seem to work nor change the grubenv file. It just kept coming back to the original grub menu as if nothing had been done.

So I ended up doing it manually and it has been working (not sure how it would work with RAID drives, though).

sudo grub-editenv - set next_entry=2
reboot

Where the 2 is the zero-based menu entry location for the Windows entry in the grub start-up menu.

You can see why this works by looking at the /boot/grub/grub.cfg file, as it uses the next_entry value and then resets it for the next boot.

1

A super easy way to do it is with the GRUB Reboot GNOME Shell Extension (that is, if you're using GNOME).

To use the extension, go to the site linked above, and click the little toggle in the top right corner (it probably says Off when you first navigate to the page). You will be asked to confirm that you would like to download and install the extension.

Once it is installed, you can open your System menu and click the power button as you normally would for a restart. The window that pops up confirming that you would like to shutdown or restart now has a button labelled "Restart to...". When you click that button, the items in your grub menu appear in the list so that you can select which OS to automatically launch after restarting. If you select one of those items, your system will shut down and restart using your selected grub options.

3
  • 1
    I edited my post to include details of installing and using the extension. Commented Nov 16, 2018 at 17:59
  • 1
    Sadly, that extension is now unmantained and not compatible with modern versions of GNOME.
    – adlr0
    Commented Aug 20, 2021 at 18:55
  • "This will not work on gnome shell 3.34+."
    – endolith
    Commented Jun 6, 2022 at 19:20
1

For those using UEFI devices, it might be better to manipulate the UEFI Boot Manager to achieve the similar result. For Linux, just run sudo efibootmgr --bootnext XXXX to set the UEFI NextBoot variable, and XXXX can be queried using sudo efibootmgr, for Boot0000 it's 0000. Then just reboot.

UEFI is an earlier process than grub, so this solution is more versatile than editing grub next boot option when using UEFI devices. For Windows, there is a tool: GitHub - Toxblh/WinToLinux doing the similar thing, but as far as I know, there is no tool in Windows that can edit grub option directly.

0

Reboot the machine to a specific boot target (Grub entry).
The boot target is interactivly selected with fzf.

# Search for grub.cfg
GRUB_CFG=$(find /boot -name grub.cfg 2> /dev/null)

if [[ -z ${GRUB_CFG} ]]; then
  echo "No grub.cfg found under /boot. Try as root."
  exit 1
elif [[ ! -r ${GRUB_CFG} ]]; then
  echo "${GRUB_CFG} is not readable. Try as root."
  exit 1
fi

GRUB_MENUENTRY=$(awk -F\' '/menuentry / {print $2}' ${GRUB_CFG} | fzf)

# Set boot target for next boot
grub2-reboot "${GRUB_MENUENTRY}"

reboot
0

As other comments suggested, changing GRUB_DEFAULT and update-grub is not required on newer systems (arch myself).

List the available menu entries (thanks Simon Schürg):

  • awk -F\' '/menuentry / {print $2}' /boot/grub/grub.cfg

Now reboot into your preferred boot option:

  • sudo grub-reboot 'Windows Boot Manager (on /dev/nvme1n1p1)' && sudo reboot
  • sudo grub-reboot 'UEFI Firmware Settings' && sudo reboot

You can also specify by index, just like GRUB_DEFAULT.

  • sudo grub-reboot '1>2' && sudo reboot
  • sudo grub-reboot 2 && sudo reboot

(Note: sudo isn't always required for reboot, but it is required for grub-reboot).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .