#!/bin/bash # This script reads kernel information from the GRUB menu to pass to "kexec". # Save a script as, e.g., /usr/local/sbin/kexec-reboot and make it executable # using chmod +x. # The script takes an item number as its first parameter. E.g., to boot the # first item in the GRUB menu, type: # kexec-reboot 1 # Alternatively, if no number is given, the script will interactively prompt # for a number. # The error checking is very basic. # Written by Isaac G, 2010 # Modified by Greg Fitzgerald, 2011 # Ripped from the Arch Wiki "kexec" page 7 May 2012: # https://wiki.archlinux.org/index.php?title=kexec die () { tput setaf 1 # Red text echo "Error: $@" >&2 tput sgr0 # Reset exit 1 } (( UID != 0 )) && die "You need to be superuser" probe () { test -e "$1" || return GRUB_CONFIG="$1" GRUB_TITLE="$2" # Command for menu item name GRUB_KERNEL="$3" # Command for boot image } # Config file for Grub 2 overrides original "legacy" one probe /boot/grub/grub.cfg menuentry linux || probe /boot/grub/menu.lst title kernel || die "No Grub configuration found" # Use the first parameter or show a menu if none is specified unset number if [[ $1 ]] ; then # Make sure the selected number is an integer [[ $1 = *[^0-9]* ]] && die "The selected parameter is not a number" number=$1 else # Nothing selected; pull up a list of options from the grub menu oldIFS="$IFS" IFS=$'\n' # Get the menu items options=( $(awk '$1 == "'"$GRUB_TITLE"'" {for (i = 2; i <= NF; i++) printf "%s ", $i; printf "\n";}' "$GRUB_CONFIG" ) ) # Ask the user to select one select title in "${options[@]}" ; do for ((i = 0; i < ${#options[@]}; i++)); do [[ $title == "${options[i]}" ]] && number=$((i + 1)) && break done [[ $number ]] && break done IFS="$oldIFS" fi unset kernel unset initrd unset append item=0 # Parse GRUB's configuration file while read key val extra; do [[ $key = "$GRUB_TITLE" ]] && ((item++)) # Count the number of menu items (( item == number )) || continue # Wait until the right number [[ $key = "$GRUB_KERNEL" ]] && kernel="$val" && append="$extra" [[ $key = "initrd" ]] && initrd="$val" done < "$GRUB_CONFIG" [[ $kernel ]] || die "No such kernel with that number" # http://stackoverflow.com/questions/2167558/give-the-mount-point-of-a-path root="$(df /boot | tail -n 1 | awk '{ print $NF}')" set -- "$root$kernel" [[ -n "${initrd+set}" ]] && set -- "$@" --initrd="$root$initrd" set -- "$@" --append="$append" kexec "$@"