34

I have a Ubuntu - Windows 7 dual-boot set-up, and I would like to have it that my laptop would boot up Windows 7 unless I press down the Shift key right after boot and bring up the Grub2 menu from which I can choose Ubuntu.

I researched on Grub2 and options for etc/default/grub and I have tried playing around with combinations with the GRUB_TIMEOUT and GRUB_HIDDEN_TIMEOUT values, but to no avail. I tried setting the GRUB_HIDDEN_TIMEOUT higher than the GRUB_TIMEOUT thinking that both countdown start simultaneously, but no - GRUB_TIMEOUT only starts after the other is done.

Is this behavior achievable?

If so, how?

3
  • 1
    The way I do it is I have the timeout set to 0 (Set using Grub Customizer). I am able to have no GRUB2 menu appear unless I hold shift right after my bios, which then displays the menu. sudo add-apt-repository ppa:danielrichter2007/grub-customizer sudo apt-get update sudo apt-get install grub-customizer Mar 31, 2012 at 5:18
  • It's my understanding this is the default behavior for some installations Mar 31, 2012 at 5:41
  • @RyanMcClure I tried setting the timeout manually to 0 but holding down right-Shift does not bring up the Grub2 menu at all. Mar 31, 2012 at 16:17

13 Answers 13

16

I think that I found a simpler resolution. Modify the following lines in the file /etc/default/grub :

GRUB_HIDDEN_TIMEOUT=0.0

GRUB_TIMEOUT=0.0

Of course we finally run an update-grub. It works on my PC.

1
  • 7
    Scratch that. This does not give me the grub menu but I also can't get it by pressing shift.
    – zorkerz
    Nov 11, 2016 at 17:29
10

This is for Ubuntu 16.04.

I solved this with a little combination of some of the answers found above, so it is not necessary to modify 30_os-prober, avoiding future merges when the grub package is updated...

Hope it helps.

Changed some variables in /etc/default/grub to reflect what I want;

GRUB_DEFAULT=4
GRUB_HIDDEN_TIMEOUT=5
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

GRUB_FORCE_HIDDEN_MENU="true"
export GRUB_FORCE_HIDDEN_MENU

Then created a new file;

sudo touch /etc/grub.d/50_hidemenu
sudo chmod +x /etc/grub.d/50_hidemenu

filled it with this content;

#!/bin/sh
cat <<EOF
if [ "x\${timeout}" != "x-1" ]; then
  if keystatus; then
    if keystatus --shift; then
      set timeout=-1
    else
      set timeout=0
    fi
  else
    if sleep --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then
      set timeout=0
    fi
  fi
fi
EOF

and updated grub;

sudo update-grub

Cheers.

4
  • Not working for me.
    – Menasheh
    Dec 30, 2016 at 17:33
  • I've only tested this in 16.04. Are you on a different version?
    – tux1c
    May 19, 2017 at 0:25
  • Might have been 16.10. You're right, definitely should have mentioned that.
    – Menasheh
    May 19, 2017 at 1:30
  • Works on Debian squeeze as well Nov 14, 2017 at 23:09
7

In Kubuntu 14.04, this does not work, if you set GRUB_TIMEOUT= 0, strangely, after applying this and rebooting, the grub menu remains visible for 10s.

The reason for this is that in another grub script there is a piece of code that sets grub_timeout to 10 if it has the value of 0.

So this is how i got it to work:

make a copy of both grub and 30_osprober files !!! When something goes wrong, you can put the original files back

In /etc/default/grub

GRUB_DEFAULT=4    #set this value to the OS you want to boot
GRUB_HIDDEN_TIMEOUT=0

GRUB_TIMEOUT=0

in /etc/grub.d/30_os-prober, there is a piece of code that sets grub timeout to 10s if it is set to zero in /etc/default/grub, I don't know why the devs put it there, but it prevents hiding the grub menu.

set timeout_style=menu

if [ "\${timeout}" = 0 ]; then    
  set timeout=10  # I changed this from 10 to 0

After these changes, run sudo update-grub to generate the new grub boot sequence.

I document all my linux fixes/mods on https://sites.google.com/site/marcshomesite/Home/linux-tuning

1
  • I hope you did not put a space after = in GRUB_TIMEOUT= 0.
    – muru
    Jul 30, 2014 at 18:34
4

To automatically boot Windows without having to select from the GRUB menu we need to edit the /etc/default/grub file with values similar to these:

GRUB_DEFAULT= <number of default entry starting from 0>
GRUB_TIMEOUT= 0 # time in seconds to boot default
# GRUB_HIDDEN_TIMEOUT=0 # warning: activating this may lock you out from GRUB menu

It is always a good idea to make backups of these files before you edit them. After having made changes we need to activate them with

sudo update-grub

Values for GRUB_DEFAULT depend on our individual system. To always boot Windows we can alternatively put in the name of the entry exactly as it was shown in the Grub menu (e.g. "Microsoft Windows XP Professional") instead of the entry number.


Important note: in some machines GRUB menu can not be displayed with pressing and holding left Shift on boot (see bug #425979). Therefore it may be a good idea to first test this with booting Ubuntu (not Windows) set as default OS. Then you will be able to easily undo your GRUB settings in case you are affected.

9
  • Doesn't that render Ubuntu humanly unbootable, or will there be enough time to intercept the boot and choose Ubuntu when I want to? Mar 31, 2012 at 15:25
  • 1
    @Shasteriskt you should set the timeout to a value just long enough to press a key for selecting another boot OS.
    – Takkat
    Mar 31, 2012 at 16:15
  • I set the timeout to 0 and held down the Shift key but the menu still does not show. (Good thing I set it to boot to Ubuntu where I can edit the settings to the way they were.) Mar 31, 2012 at 16:22
  • In short, the behavior I need is not achievable? Mar 31, 2012 at 16:31
  • @Shasteriskt: unfortunately on some machines the press-and-hold-left-SHIFT during boot to bring up GRUB menu is broken (e.g. this bug). You may be lucky in case ESC or SHIFT+ESC works.
    – Takkat
    Mar 31, 2012 at 19:50
4

I was trying to do the same and I found great help in the Ubuntu Forums, particularly in this thread.

Assuming you did the right thing with /etc/default/grub, correctly setting GRUB_TIMEOUT and GRUB_HIDDEN_TIMEOUT (I'd say respectively to 0 and 5) and even GRUB_DEFAULT to specify the default image to boot, here's the procedure to have it work the right way.

  1. Add those lines

    GRUB_FORCE_HIDDEN_MENU="true"
    export GRUB_FORCE_HIDDEN_MENU
    

    to the end of /etc/default/grub

  2. Backup your /etc/grub.d/30_os-prober and overwrite it with the version found here

  3. Test it! To show the menu press the SHIFT key

This problem is related to the multi OS setup and editing the script is one of the way to correct that.

30_os-prober:

#! /bin/sh
set -e

# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"

. "${datarootdir}/grub/grub-mkconfig_lib"

found_other_os=

make_timeout () {

  if [ "x${found_other_os}" = "x" ] || [ "x${GRUB_FORCE_HIDDEN_MENU}" = "xtrue" ] ; then 
    if [ "x${1}" != "x" ] ; then
      if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
    verbose=
      else
    verbose=" --verbose"
      fi

      if [ "x${1}" = "x0" ] ; then
    cat <<EOF
if [ "x\${timeout}" != "x-1" ]; then
  if keystatus; then
    if keystatus --shift; then
      set timeout=-1
    else
      set timeout=0
    fi
  else
    if sleep$verbose --interruptible 3 ; then
      set timeout=0
    fi
  fi
fi
EOF
      else
    cat << EOF
if [ "x\${timeout}" != "x-1" ]; then
  if sleep$verbose --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then
    set timeout=0
  fi
fi
EOF
      fi
    fi
  fi
}

adjust_timeout () {
  if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
    cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
    make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}"
    echo else
    make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
    echo fi
  else
    make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
  fi
}

if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
  adjust_timeout
  exit 0
fi

if [ -z "`which os-prober 2> /dev/null`" -o -z "`which linux-boot-prober 2> /dev/null`" ] ; then
  # missing os-prober and/or linux-boot-prober
  adjust_timeout
  exit 0
fi

OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`"
if [ -z "${OSPROBED}" ] ; then
  # empty os-prober output, nothing doing
  adjust_timeout
  exit 0
fi

osx_entry() {
    found_other_os=1
        cat << EOF
menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" --class osx --class darwin --class os {
EOF
    save_default_entry | sed -e "s/^/\t/"
    prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
    cat << EOF
        load_video
        set do_resume=0
        if [ /var/vm/sleepimage -nt10 / ]; then
           if xnu_resume /var/vm/sleepimage; then
             set do_resume=1
           fi
        fi
        if [ \$do_resume = 0 ]; then
           xnu_uuid ${OSXUUID} uuid
           if [ -f /Extra/DSDT.aml ]; then
              acpi -e /Extra/DSDT.aml
           fi
           $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid
           if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
              xnu_mkext /System/Library/Extensions.mkext
           else
              xnu_kextdir /System/Library/Extensions
           fi
           if [ -f /Extra/Extensions.mkext ]; then
              xnu_mkext /Extra/Extensions.mkext
           fi
           if [ -d /Extra/Extensions ]; then
              xnu_kextdir /Extra/Extensions
           fi
           if [ -f /Extra/devprop.bin ]; then
              xnu_devprop_load /Extra/devprop.bin
           fi
           if [ -f /Extra/splash.jpg ]; then
              insmod jpeg
              xnu_splash /Extra/splash.jpg
           fi
           if [ -f /Extra/splash.png ]; then
              insmod png
              xnu_splash /Extra/splash.png
           fi
           if [ -f /Extra/splash.tga ]; then
              insmod tga
              xnu_splash /Extra/splash.tga
           fi
        fi
}
EOF
}

wubi=

for OS in ${OSPROBED} ; do
  DEVICE="`echo ${OS} | cut -d ':' -f 1`"
  LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
  LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`"
  BOOT="`echo ${OS} | cut -d ':' -f 4`"

  if [ -z "${LONGNAME}" ] ; then
    LONGNAME="${LABEL}"
  fi

  echo "Found ${LONGNAME} on ${DEVICE}" >&2

  case ${BOOT} in
    chain)

      case ${LONGNAME} in
    Windows*)
      if [ -z "$wubi" ]; then
        if [ -x /usr/share/lupin-support/grub-mkimage ] && \
           /usr/share/lupin-support/grub-mkimage --test; then
          wubi=yes
        else
          wubi=no
        fi
      fi
      if [ "$wubi" = yes ]; then
        echo "Skipping ${LONGNAME} on Wubi system" >&2
        continue
      fi
      ;;
      esac

      found_other_os=1
      cat << EOF
menuentry "${LONGNAME} (on ${DEVICE})" --class windows --class os {
EOF
      save_default_entry | sed -e "s/^/\t/"
      prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"

      case ${LONGNAME} in
    Windows\ Vista*|Windows\ 7*|Windows\ Server\ 2008*)
    ;;
    *)
      cat << EOF
    drivemap -s (hd0) \${root}
EOF
    ;;
      esac

      cat <<EOF
    chainloader +1
}
EOF
    ;;
    linux)
      LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
      prepare_boot_cache=

      for LINUX in ${LINUXPROBED} ; do
        LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
        LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
        LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`"
        LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
        LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
        LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`"

        if [ -z "${LLABEL}" ] ; then
          LLABEL="${LONGNAME}"
        fi

    if [ "${LROOT}" != "${LBOOT}" ]; then
      LKERNEL="${LKERNEL#/boot}"
      LINITRD="${LINITRD#/boot}"
    fi

    if [ -z "${prepare_boot_cache}" ]; then
      prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | sed -e "s/^/\t/")"
      [ "${prepare_boot_cache}" ] || continue
    fi
    found_other_os=1
        cat << EOF
menuentry "${LLABEL} (on ${DEVICE})" --class gnu-linux --class gnu --class os {
EOF
    save_default_entry | sed -e "s/^/\t/"
    printf '%s\n' "${prepare_boot_cache}"
    cat <<  EOF
    linux ${LKERNEL} ${LPARAMS}
EOF
        if [ -n "${LINITRD}" ] ; then
          cat << EOF
    initrd ${LINITRD}
EOF
        fi
        cat << EOF
}
EOF
      done
    ;;
    macosx)
      OSXUUID="`grub-probe --target=fs_uuid --device ${DEVICE} 2> /dev/null`"
      osx_entry xnu_kernel 32
      osx_entry xnu_kernel64 64
    ;;
    hurd)
      found_other_os=1
      cat << EOF
menuentry "${LONGNAME} (on ${DEVICE})" --class hurd --class gnu --class os {
EOF
      save_default_entry | sed -e "s/^/\t/"
      prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
      grub_device="`${grub_probe} --device ${DEVICE} --target=drive`"
      mach_device="`echo "${grub_device}" | sed -e 's/(\(hd.*\),msdos\(.*\))/\1s\2/'`"
      grub_fs="`${grub_probe} --device ${DEVICE} --target=fs`"
      case "${grub_fs}" in
    *fs)    hurd_fs="${grub_fs}" ;;
    *)  hurd_fs="${grub_fs}fs" ;;
      esac
      cat << EOF
    multiboot /boot/gnumach.gz root=device:${mach_device}
    module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
            --multiboot-command-line='\${kernel-command-line}' \\
            --host-priv-port='\${host-port}' \\
            --device-master-port='\${device-port}' \\
            --exec-server-task='\${exec-task}' -T typed '\${root}' \\
            '\$(task-create)' '\$(task-resume)'
    module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
}
EOF
    ;;
    *)
      echo "  ${LONGNAME} is not yet supported by grub-mkconfig." >&2
    ;;
  esac
done

adjust_timeout


    cat <<EOF
if [ "x\${timeout}" != "x-1" ]; then
  if keystatus; then
    if keystatus --shift; then
      set timeout=-1
    else
      set timeout=0
    fi
  else
    if sleep$verbose --interruptible 3 ; then
      set timeout=0
    fi
  fi
fi
EOF
4
  • 1
    I tried your method and it failed. Ubuntu 14.04 LTS Apr 15, 2014 at 10:32
  • 1
    What parts of the file should I change? My 14.04 file has many differences with this file, so I suppose I should make only targeted changes.
    – MakisH
    Nov 30, 2014 at 9:33
  • @MayukhNair: I have Ubuntu 14.04 and this method worked. I did the following - 1. Set GRUB_DEFAULT=0 in /etc/default/grub 2. Set GRUB_HIDDEN_TIMEOUT=0 (unlike what Dariopnc said) 3. Backup your /etc/grub.d/30_os-prober and copy paste the above mentioned 30-os_prober file 4. sudo update-grub2 Dec 30, 2014 at 19:37
  • Note grub needs to be updated with sudo update-grub after changing the /etc/default/grub file
    – Wilf
    Jan 12, 2015 at 21:41
3

On Ubuntu 16.04 I've done the following changes. Of course you need to be a privileged user to do so.

  1. First change is in the /etc/grub.d/30_os-prober file:

    • Open it with sudo gedit /etc/grub.d/30_os-prober
    • Change quick_boot="1" to quick_boot="0"
    • save the file
  2. Thereafter you can set the timeout values in /etc/default/grub to zero or some other value:

    • Open it with sudo gedit /etc/default/grub
    • GRUB_HIDDEN_TIMEOUT=0 and GRUB_TIMEOUT=0.
    • save the file
  3. The last step is to update grub

    • sudo update-grub

The changes to the first file are because the default setting is that if other OS (e. g. Windows 10) are found the timeout value is always set to 10 seconds and therefore cannot be changed by /etc/default/grub. This is accomplished by a function named adjust_timeout which asks if quick_boot is set and if other OS are present.

1
  • Finally somzing zat vorks wiz 16.04!
    – JLTD
    May 27, 2017 at 13:59
2

install grub optimizer

sudo add-apt-repository ppa:danielrichter2007/grub-customizer

sudo apt-get update
sudo apt-get install grub-customizer

Grub Customizer will now show up in the Applications > System Tools menu.

Or you can open it from the command line.

gksudo grub-customizer

image inside for grub options

enter image description here

3
  • 3
    What can this do that cannot be done by editing etc/default/grub? Mar 31, 2012 at 16:19
  • 3
    @Shasteriskt: it can be useful to non-English speakers, people who aren't familiar with the command-line, or people who just want to use a computer and not muck around with configuration files.
    – Flimm
    Apr 16, 2013 at 12:02
  • Why has this been upvoted? It doesn't seem to solve any problems; I have tried grub-customizer (not 'optimizer') and, while working, it does not help me ot hide GRUB menu unless Shift key is pressed. Aug 31, 2015 at 1:33
1

I was having the same problem on a single boot system. If GRUB_TIMEOUT was non-zero the menu would always popped up regardless of GRUB_HIDDEN_TIMEOUT. If GRUB_TIMEOUT was zero it would sleep for GRUB_HIDDEN_TIMEOUT seconds but neither SHIFT nor ESC would show the menu.

I fixed it by adding an else clause to the sleep statment at the end of adjust_time() in 30_os-prober. Now if it isn't interrupted the timeout is zero and it boots with no menu, but if it is interrupted I set the timeout to 10.

This actually seems backwards since sleep should return 0 (false) if it's not interrupted and 1 (true) if it is but it seemed to work for me.

1

Just to finalize this discussion:

I do NOT recommend anyone to edit the "30_os-prober" file! (the code is there for a reason!)

The right way to fix the issue is to disable fast-boot in your windows installation as described here (for Win8) and here (for Win10).

After doing this you need to SHUTDOWN (not reboot) your PC to prevent windows from creating files which get loaded on start-up to boot faster.

Now, if grub is configured correctly, it should work as intended without editing the "30_os-prober" file, because the "[ "$quick_boot" = 1 ]" check in the if condition posted above returns 0.

0

MAKING THE GRUB2 BOOT MENU AUTOMATICALLY VISIBLE

For some reason, editing the GRUB_GFXMODE=640x480 settings in the Grub Customizer usually makes the boot menu visible:

  1. Install grub-customizer as above and update
  2. find Grub Customizer in the GUI (for me it's in System>Administration>..., but for some it is fund under Applications>System Tools>..)
  3. Open Grub Customizer and select Preferences> Advanced
  4. Select GRUB_gfxmode (640X480) - if it is already selected, deselect it, reboot, and select it again.
  5. cross your fingers and reboot!

I have no idea why this worked for me, but it worked on both of my computers, so hopefully it will work for you too!

0

Shasteriskt, one alternative to the 'SHIFT' solution is just to create a script that does some move operations for you. What I mean is create a file called grub.bak that is an exact copy of your grub.cfg file, with the only difference being that the set timeout=0 line is changed to set timeout=10 for example. Create a shell script that does a switch allowing you to reboot according to your needs. I created an equivalent python script that fulfills these requirements, but of course it has to be called with sudo. I simply put it into /usr/bin on my setup as a symlink to the actual script itself. Note: I am running fluxbox on Arch so I'm not sure if there are any discrepancies between this script and Ubuntu, but there should be little to no modifications, I think. Script looks like:

#! /usr/bin/python
from shlex import split
from subprocess import call
from os import rename, chdir

chdir('/boot/grub/')
try:
    with open('grub.bak','r') as alternate:
        pass
    if raw_input('Auto-boot is set. Un-set?> ') == 'y':
        rename('grub.cfg','grub.back')
        rename('grub.bak','grub.cfg')

    if raw_input('Reboot system?> ') == 'y':
        call(split('shutdown -r now'))

except:
    if raw_input('Auto-boot is not set. Set?> ') == 'y':
        rename('grub.cfg','grub.bak')
        rename('grub.back','grub.cfg')

    if raw_input('Reboot system?> ') == 'y':
        call(split('shutdown -r now'))

The script basically just determines whether or not you have the menu to load or not (auto-boot or not). Based on its findings, it asks you if you would like to turn it on or off, and then asks if you if you want to reboot. Conversely, if you want it to work the other way around (i.e. in Windows), and you have Windows set up to access files in Linux, you can run the same script in that environment as well, if you wish. Hope that helps.

0

So even if you set GRUB_TIMEOUT to 0, if you have any GRUB_HIDDEN_TIMEOUT, 30_os-prober will set timeout to 10 whether you like it or not. Other solutions here edit that script, but that could cause update issues you'll have to merge if GRUB is updated.

Better solution: write the following in /etc/grub.d/50_goddamnit (new file):

#!/bin/sh
echo "set timeout=0"

Basically, this will run last and be the final line in /boot/grub/grub.conf, thereby overriding all the other silly mishigus in the default config.

0

If you have a single operating system, that is, for example, Ubuntu 18.04 only, edit /etc/default/grub:

$ sudo vim /etc/default/grub

Change the following lines as shown:

GRUB_TIMEOUT_STYLE=hidden  
GRUB_TIMEOUT=1

If you are dual booting, for example Ubuntu 18.04 + Windows 10, edit /etc/grub.d/30_os-prober:

$ sudo vim /etc/grub.d/30_os-prober

Change the following lines as shown:

adjust_timeout () {  
  if [ "$quick_boot" = 1 ] && [ "x${found_other_os}" != "x" ]; then  
    cat << EOF  
set timeout_style=hidden
if [ "\${timeout}" = 0 ]; then  
  set timeout=1
fi  
EOF  
  fi  
}

Finally update GRUB:

$ sudo update-grub  

OK! Now you have 1 second to press ESC to display GRUB2 menu.

You must log in to answer this question.

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