CentOS 7 learn used grub entry

With the major changes introduced in CentOS 7 from CentOS 6 (systemd, grub2, and more), determining exactly which grub menu entry will be used at next boot is a little more difficult than before.

I wrote a quick script that calculates this for you: learn-used-grub-entry

#!/bin/sh
# File: learn-used-grub-entry
# Location: /usr/bin
# Author: bgstack15
# Startdate: 2019-01-28 11:27
# Title: Script that Determines Which Grub Entry Will be Used
# Purpose:
# Package: bgscripts
# History:
# Usage:
#    for RHEL7/grub2
# Reference:
#    original research
# Improve:

test -z "${LUGE_GRUB_CFG}" && LUGE_GRUB_CFG=/boot/grub2/grub.cfg
test -z "${LUGE_ETC_DEFAULT_GRUB}" && LUGE_ETC_DEFAULT_GRUB=/etc/default/grub
# use option LUGE_OUTPUT which is one of ["kernel","","initram"]

grub_saved_name="$( grub2-editenv - list | awk -F'=' '{print $NF}' )"
use_number="$( awk -F'=' '/^GRUB_DEFAULT/{print $NF}' "${LUGE_ETC_DEFAULT_GRUB}" )"

use_entry=""
# calculate true value
if test "$( echo "${use_number}" | tr '[[:upper:]]' '[[:lower:]]' )" = "saved" ;
then
   # it is the saved value (which is same as last used)
   use_entry="${grub_saved_name}"
else
   # calculate used name from number
   use_entry="$( grep -E -e '^menuentry' "${LUGE_GRUB_CFG}" | sed -r -n -e "$(( use_number + 1 ))p" )"
fi

# calculate which value to display or just display name
LUGE_grep=1
case "${LUGE_OUTPUT:-${1}}" in

   "num" | "number" )
      # just show the number
      unset LUGE_grep
      echo "${use_number}"
      ;;

   "kernel"|"vmlinuz" )
      # show kernel
      LUGE_regex="linux(16|32|64)"
      LUGE_awk_val='$2'
      ;;

   "initram" | "initrd" | "initramfs" )
      # show initram
      LUGE_regex="initrd|initram"
      LUGE_awk_val='$2'
      ;;

   *)
      # DEFAULT VALUE, so mistyped or not defined
      unset LUGE_grep
      echo "${use_entry}"
      ;;
esac

# show complicated value if necessary
if test -n "${LUGE_grep}" ;
then
   sed -n -r -e "/${use_entry}/,/^\s*\}/p" "${LUGE_GRUB_CFG}" | awk "/${LUGE_regex}/{print ${LUGE_awk_val}}"
fi

# exit cleanly
true
Advertisements

Update /etc/default/grub programmatically

My latest bgconf package includes my grub preferences for RHEL-based systems.

I allow for environment variable overrides, but the defaults are to disable rhgb and quiet. If you have been looking for a way to easily remove red hat graphical boot (rhgb) so you can actually see the kernel messages scroll by, you want this script.

#!/bin/sh

# DEFINE FUNCTIONS

clean_mgm() {
   rm -rf "${MGM_TMPDIR}" 2>/dev/null
}

update_grub_if_changed() {
   # call: update_grub_if_changed "${MGM_INFILE}" "${MGM_TMPFILE1}"

   local infile="${1}"
   local tmpfile="${2}"

   # determine if changes were made to the file
   if diff -q "${infile}" "${tmpfile}" 2>&1 | grep -qiE 'differ' ;
   then
      # changes were made
      if fistruthy "${MGM_APPLY}" ;
      then
         sudo /bin/cp -p "${tmpfile}" "${infile}"
         sudo /usr/sbin/grub2-mkconfig -o "${MGM_GRUB_FILE:-/boot/grub2/grub.cfg}"
      fi
   else
      # no changes
      :
   fi

}

add_value_to_grub_line() {
   # call: add_value_to_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "quiet"

   local infile="${1}"
   local thisvar="${2}"
   local thisvalue="${3}"

   sed -i -r -e "/^${thisvar}=/{ /${thisvalue}/! { s/\"\s*\$/${thisvalue}\"/; } ; }" "${infile}"

}

remove_value_from_grub_line() {
   # call: remove_value_from_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "quiet"

   local infile="${1}"
   local thisvar="${2}"
   local thisvalue="${3}"

   sed -i -r -e "/^${thisvar}=/{ /${thisvalue}/ { s/\s*${thisvalue}//; } ; }" "${infile}"

}

# REACT TO OS
# fail out if not rhel-based
. /usr/share/bgscripts/framework.sh
case "${thisflavor}" in
   fedora|el|centos|korora) : ;;
   *) exit 0 ;;
esac

# set variables
test -z "${MGM_TMPDIR}" && MGM_TMPDIR="$( mktemp -d )"
test -z "${MGM_TMPFILE1}" && MGM_TMPFILE1="$( TMPDIR="${MGM_TMPDIR}" mktemp )"

test -z "${MGM_INFILE}" && MGM_INFILE=/etc/default/grub
test -z "${MGM_GRUB_FILE}" && MGM_GRUB_FILE=/boot/grub2/grub.cfg
test -z "${MGM_APPLY}" && MGM_APPLY=yes
test -z "${MGM_RHGB}" && MGM_RHGB=no
test -z "${MGM_QUIET}" && MGM_QUIET=no

# clean up temp file if necessary
test ! -e "${MGM_TMPFILE1}" && { touch "${MGM_TMPFILE1}" || exit 1 ; }
cat "${MGM_INFILE}" > "${MGM_TMPFILE1}"
trap '__ec=$? ; clean_mgm ; trap "" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; exit ${__ec:-0} ;' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

# Do the RHGB action
if fistruthy "${MGM_RHGB}" ;
then
   # add rhgb to grub config
   add_value_to_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "rhgb"
else
   # remove rhgb
   remove_value_from_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "rhgb"
fi

# Do the QUIET action
if fistruthy "${MGM_QUIET}" ;
then
   # add quiet to grub config
   add_value_to_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "quiet"
else
   # remove quiet
   remove_value_from_grub_line "${MGM_TMPFILE1}" "GRUB_CMDLINE_LINUX" "quiet"
fi

# Determine if any changes occurred to the file
update_grub_if_changed "${MGM_INFILE}" "${MGM_TMPFILE1}"

# show final results
fistruthy "${MGM_VERBOSE}" && cat "${MGM_TMPFILE1}"