Skip to content

Instantly share code, notes, and snippets.

@HackingGate
Last active January 22, 2026 12:34
Show Gist options
  • Select an option

  • Save HackingGate/ce56647c87fc8a4131cd8e9b67615966 to your computer and use it in GitHub Desktop.

Select an option

Save HackingGate/ce56647c87fc8a4131cd8e9b67615966 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
# Check if running as root, if not, re-run with sudo
if [ "$EUID" -ne 0 ]; then
echo "This script needs to read grub.cfg and modify boot settings."
echo "Re-running with sudo..."
exec sudo "$0" "$@"
fi
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# Arrays to hold all boot entries and their types
declare -a ALL_ENTRIES
declare -a ENTRY_TYPES
declare -a ENTRY_DATA
# 0) Pick grub.cfg path (prefer grub2 layout) and read GRUB entries
CFG=""
if [ -r /boot/grub2/grub.cfg ]; then
CFG="/boot/grub2/grub.cfg"
elif [ -r /boot/grub/grub.cfg ]; then
CFG="/boot/grub/grub.cfg"
fi
if [ -n "$CFG" ]; then
# 1) Read every top‑level menuentry title (handles leading whitespace & both quote styles)
mapfile -t GRUB_ENTRIES < <(
grep -E "^[[:space:]]*menuentry [\"'].*[\"']" "$CFG" \
| sed -E "s/^[[:space:]]*menuentry [\"']([^\"']+)[\"'].*/\1/"
)
for entry in "${GRUB_ENTRIES[@]}"; do
ALL_ENTRIES+=("$entry")
ENTRY_TYPES+=("GRUB")
ENTRY_DATA+=("$entry")
done
fi
# 2) Check for EFI boot entries
if command -v efibootmgr >/dev/null 2>&1; then
# Parse efibootmgr output to get boot entries
# Format: Boot0000* Ubuntu
mapfile -t EFI_RAW < <(efibootmgr | grep -E "^Boot[0-9A-F]{4}\*?" || true)
for line in "${EFI_RAW[@]}"; do
# Extract boot number (e.g., "0000") and name
if [[ "$line" =~ ^Boot([0-9A-F]{4})(\*?)[[:space:]]+(.+)$ ]]; then
BOOT_NUM="${BASH_REMATCH[1]}"
BOOT_NAME="${BASH_REMATCH[3]}"
ALL_ENTRIES+=("[EFI] $BOOT_NAME")
ENTRY_TYPES+=("EFI")
ENTRY_DATA+=("$BOOT_NUM")
fi
done
fi
if [ ${#ALL_ENTRIES[@]} -eq 0 ]; then
echo "No GRUB or EFI boot entries found" >&2
exit 1
fi
# 3) Print numbered menu
echo "Select which OS (or kernel) to boot *next* time only:"
for i in "${!ALL_ENTRIES[@]}"; do
printf " %2d) %s\n" "$i" "${ALL_ENTRIES[$i]}"
done
echo
# 4) Prompt
read -rp "Enter choice number: " CHOICE
# 5) Validate
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || (( CHOICE < 0 || CHOICE >= ${#ALL_ENTRIES[@]} )); then
echo "Invalid selection." >&2
exit 1
fi
# 6) Handle boot based on entry type
ENTRY_TYPE="${ENTRY_TYPES[$CHOICE]}"
ENTRY_INFO="${ENTRY_DATA[$CHOICE]}"
if [ "$ENTRY_TYPE" = "GRUB" ]; then
# Find the proper grub reboot command
if command -v grub-reboot >/dev/null 2>&1; then
GRUB_REBOOT_CMD="grub-reboot"
elif command -v grub2-reboot >/dev/null 2>&1; then
GRUB_REBOOT_CMD="grub2-reboot"
else
echo "Neither grub-reboot nor grub2-reboot found in PATH." >&2
exit 1
fi
echo "Will reboot into GRUB entry \"$ENTRY_INFO\" on next boot…"
"$GRUB_REBOOT_CMD" "$ENTRY_INFO"
elif [ "$ENTRY_TYPE" = "EFI" ]; then
echo "Will reboot into EFI entry \"${ALL_ENTRIES[$CHOICE]}\" on next boot…"
efibootmgr --bootnext "$ENTRY_INFO"
fi
reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment