From 692c3612904bbcb0f8afd8f6a8f5b47be1a69dab Mon Sep 17 00:00:00 2001 From: David Thurstenson Date: Wed, 1 Dec 2021 18:12:19 -0600 Subject: [PATCH] nextboot: merge picksdboot and pickefi into one function --- bin/nextboot | 85 ++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/bin/nextboot b/bin/nextboot index a400f22..5f25425 100755 --- a/bin/nextboot +++ b/bin/nextboot @@ -10,67 +10,54 @@ bootctl is-installed &> /dev/null && sdboot=1 [[ "$(bootctl reboot-to-firmware)" == "supported" ]] && fwboot=1 -picksdboot() { - # Usage: picksdboot <prompt> - local entry PS3 COLUMNS +selectentry() { + # Usage: selectentry <title> <prompt> + local sel PS3 COLUMNS PS3="$2 " COLUMNS=1 # Print title to stderr printf "\n%s\n\n" "$1" >&2 - # Put all systemd-boot loder entry confs into an array - mapfile -t sdbootlist < <(systemctl --boot-loader-entry=help) + # Populate entry list array + # If we're in EFI mode + if [[ -v efimode ]]; then + # This one is fun + # mapfile splits stdin on \n to an array + # The sed regex looks for an asterisk in the 8th position (0 indexed), + # which marks an efi boot entry as "active", so those are the only ones + # we care to add to the list. + # It *seems* like one could put mapfile at the end of the pipeline, but + # each command gets run in a subshell, so the array is lost. (ref: SC2031) + mapfile -t entrylist < <(efibootmgr | sed -n '/.\{8\}\*/p') - # Only add the firmware interface to the list if booting to it is supported - [[ -v fwboot ]] && sdbootlist+=("$biosname") + # Add firmware interface entry if supported + [[ -v fwboot ]] && entrylist+=("$biosname") - select entry in "${sdbootlist[@]}"; do + # If we're in systemd-boot mode + elif [[ ! -v efimode ]]; then + # Put all systemd-boot loder entry confs into an array + mapfile -t entrylist < <(systemctl --boot-loader-entry=help) + + # Only add the firmware interface to the list if booting to it is supported + [[ -v fwboot ]] && entrylist+=("$biosname") + fi + + # Get user selection + select sel in "${entrylist[@]}"; do break done - printf "%s" "$entry" -} - - -pickefi() { - # Usage: pickefi <title> <prompt> - local bootnext PS3 COLUMNS - PS3="$2 " - COLUMNS=1 - - # Print title to stderr - printf "\n%s\n\n" "$1" >&2 - - # This one is fun - # mapfile splits stdin on \n to an array - # The sed regex looks for an asterisk in the 8th position (0 indexed), - # which marks an efi boot entry as "active", so those are the only ones - # we care to add to the list. - # It *seems* like one could put mapfile at the end of the pipeline, but - # each command gets run in a subshell, so the array is lost. (ref: SC2031) - mapfile -t efientries < <(efibootmgr | sed -n '/.\{8\}\*/p') - - # Rebooting to the firmware interface only works with systemd-boot, so only add - # it to the EFI mode list if systemd-boot is available and it's supported - [[ -v sdboot && -v fwboot ]] && efientries+=("$biosname") - - select efiselection in "${efientries[@]}"; do - - # If they chose the firmware interface - if [[ "$efiselection" == "$biosname" ]]; then - break - else - # Take only character 4-8 of the entry, which is the BOOTNUM - bootnext="${efiselection:4:4}" - break - fi - done - - printf "%s" "$bootnext" + # If in efi mode and the user did not select the firmware config menu item, + # then drop everything except for the BOOTNUM (character 4-8) + [[ -v efimode && "$sel" != "$biosname" ]] && sel="${sel:4:4}" + + # Print result to stdout + printf "%s" "$sel" } +# Parse command line options while getopts ":en" opt; do case $opt in e) @@ -107,7 +94,7 @@ if [[ -v efimode ]]; then fi # Prompt for the user's choice - choice="$(pickefi "$title" "$prompt")" + choice="$(selectentry "$title" "$prompt")" # A special case to boot into firmware interface if [[ "$choice" == "$biosname" ]]; then @@ -131,7 +118,7 @@ elif [[ ! -v efimode ]]; then fi # Prompt for the user's choice - choice="$(picksdboot "$title" "$prompt")" + choice="$(selectentry "$title" "$prompt")" # A special case to boot into firmware interface if [[ "$choice" == "$biosname" ]]; then