Grub bypass unless hold Shift Key

I have been trying to implement Grub Hold Shift Key.

When I follow the instructions it will just bypass and I cannot access the grub menu when shift is held down. Has anyone sucessfully added this as an option? I usually dont need to change anything in Grub at boot. This would speed things up another 5 sconds at boot.

Is it correctly created in grub.cfg?
Post

sudo grep -A 30 -E "### BEGIN /etc/grub.d/31_hold_shift" /boot/grub/grub.cfg
pacman -Qs grub
2 Likes

sudo grep -A 30 -E "### BEGIN /etc/grub.d/31_hold_shift" /boot/grub/grub.cfg

### BEGIN /etc/grub.d/31_hold_shift ###
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 3 ; then
      set timeout=0
    fi
  fi
fi
### END /etc/grub.d/31_hold_shift ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###

### BEGIN /etc/grub.d/41_snapshots-btrfs ###

pacman -Qs grub

pacman -Qs grub
local/grub 2:2.04-8
    GNU GRand Unified Bootloader (2)
local/grub-btrfs 4.7.2-1
    Include btrfs snapshots in GRUB boot options
local/grub-garuda 2.04-11
    meta pkg for grub
local/grub-theme-garuda r17.cdec99d-1
    garuda Linux grub theme
local/python-markdown 3.3.3-3
    Python implementation of John Gruber's Markdown.
local/update-grub 0.0.1-7
    Simple wrapper around grub-mkconfig

cat /etc/default/grub

# GRUB boot loader configuration

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Garuda"
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on splash rd.udev.log_priority=3 vt.global_cursor_default=0 systemd.unified_cgroup_hierarchy=1 loglevel=3"
GRUB_CMDLINE_LINUX=""

# Preload both GPT and MBR modules so that they are not missed
GRUB_PRELOAD_MODULES="part_gpt part_msdos"

# Uncomment to enable booting from LUKS encrypted devices
#GRUB_ENABLE_CRYPTODISK=y

# Set to 'countdown' or 'hidden' to change timeout behavior,
# press ESC key to display menu.
GRUB_TIMEOUT_STYLE=menu

# Hide GRUB unless the Shift key is held down
GRUB_FORCE_HIDDEN_MENU="true"

# Uncomment to use basic console
GRUB_TERMINAL_INPUT=console

# Uncomment to disable graphical terminal
#GRUB_TERMINAL_OUTPUT=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=auto
GRUB_GFXMODE=1920x1080x32,auto

# Uncomment to allow the kernel use the same resolution used by grub
GRUB_GFXPAYLOAD_LINUX=keep

# Uncomment if you want GRUB to pass to the Linux kernel the old parameter
# format "root=/dev/xxx" instead of "root=/dev/disk/by-uuid/xxx"
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entries
GRUB_DISABLE_RECOVERY=true

# Uncomment and set to the desired menu colors.  Used by normal and wallpaper
# modes only.  Entries specified as foreground/background.
#GRUB_COLOR_NORMAL="light-blue/black"
#GRUB_COLOR_HIGHLIGHT="light-cyan/blue"

# Uncomment one of them for the gfx desired, a image background or a gfxtheme
#GRUB_BACKGROUND="/path/to/wallpaper"
GRUB_THEME="/usr/share/grub/themes/garuda/theme.txt"

# Uncomment to get a beep at GRUB start
#GRUB_INIT_TUNE="480 440 1"

# Uncomment to make GRUB remember the last selection. This requires
# setting 'GRUB_DEFAULT=saved' above.
#GRUB_SAVEDEFAULT="true"

cat /etc/grub.d/31_hold_shift

#! /bin/sh
set -e

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

export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
source "${datarootdir}/grub/grub-mkconfig_lib"

found_other_os=

make_timeout () {

  if [ "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
}

  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
1 Like

This method is not 100% sure that works, as stated in Grub Manual (and Archwiki)

Checking key modifier status is only supported on some platforms. If invoked without any options, the keystatus command returns true if and only if checking key modifier status is supported.

If you want to see your hardware supports this, boot to grub menu, press C to go to grub console and run this command

keystatus

I am just translating what is already in wiki and grub developer manual.

So, check and report your findings.


Edit: You can see that there is an if keystatus check in the produced code.

2 Likes

when at the console in grub and I type keystatus, nothing happens.

I tried:

  • keystatus
  • keystatus --shft
  • keystatus --ctrl
  • keystatus --alt

Nothing is returned.

EDIT: After much more searching I have found that if I spam the Esc Key I can access the Grub menu. While not ideal this does serve the purpose intended. So this means that my laptop is not capable of keystatus?

Probably not capable.
For sure, you can check error status
In grub console

keystatus
echo $?

If output is 0 then it is capable, if it's 1 then it is not.

The script you used, when it finds that keystatus is not working, adds a 3 sec delay, so you can get to grub with the normal way (hidden menu).

This is normal (the other one is deprecated I guess).

With the hidden menu method, the GRUB_TIMEOUT value in /etc/default/grub is used as a timeout for pressing any key to grub menu, while the menu is hidden (and you are on a black screen).
I think this can do what you need.

3 Likes

Thanks

keystatus
echo $?

Returned a 1, So I guess this is a no go for MSI laptop. Thanks for helping. I really appreciate all that you have done for me.

EDIT: I just deleted the 31 hold shift file and changed the grub timeout to 3. This way the boot time is the same.

2 Likes