From 4d346881dfa86a40a8b72c44f9d1fcbbd87caa34 Mon Sep 17 00:00:00 2001 From: David Thurstenson Date: Sun, 14 Mar 2021 03:46:06 -0500 Subject: [PATCH] Handle EFI boot options as well, and an option to not reboot immediately --- bin/nextboot | 80 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/bin/nextboot b/bin/nextboot index a251b78..9d81793 100755 --- a/bin/nextboot +++ b/bin/nextboot @@ -1,15 +1,75 @@ #!/usr/bin/env bash -PS3="Select next boot entry: " -COLUMNS=1 -select entry in $(systemctl --boot-loader-entry=help) BIOS; do - if [[ "$entry" == "BIOS" ]]; then - sudo systemctl reboot --firmware-setup - exit 0 - else - sudo systemctl reboot --boot-loader-menu=1 --boot-loader-entry="$entry" - exit 0 - fi + +# The pretty name we want to give to the firmware entry +biosname="Firmware Interface" + +while getopts ":en" opt; do + case $opt in + e) + # 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) + # 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') + PS3="EFI entry to BootNext: " + COLUMNS=1 + select efiselection in "${efientries[@]}"; do + bootnext="${efiselection:4:4}" + break + done + sudo efibootmgr -q --bootnext "$bootnext" + ;; + n) + noreboot=1 + ;; + \?) + echo "E: Invalid option: -$OPTARG" >&2 + exit 1 + ;; + esac done +# If we are trying to set the EFI entry, this conditional isn't useful +if [[ -v bootnext ]]; then + : +# If we aren't trying to set the EFI entry, and systemd-boot is installed +elif [[ ! -v bootnext ]] && bootctl is-installed &> /dev/null; then + # Select prompt options + PS3="Select next boot entry: " + COLUMNS=1 + select entry in $(systemctl --boot-loader-entry=help) "$biosname"; do + if [[ "$entry" == "$biosname" ]]; then + sudo bootctl reboot-to-firmware true + break + else + sudo bootctl set-oneshot "$entry" + break + fi + done +else + # If we've made it here, then we're not trying to set the EFI entry, and + # systemd-boot is not installed in the ESP, so bail. + echo "E: systemd-boot not installed. Exiting." + exit 1 +fi + +# If we do want to reboot now, and we aren't setting the EFI entry +if [[ ! -v noreboot && ! -v bootnext ]]; then + # Reboot, and set a low timeout on the systemd-boot menu for next boot only + sudo systemctl reboot --boot-loader-menu=1 +# If we do want to reboot now, and we are setting the EFI entry +elif [[ ! -v noreboot && -v bootnext ]]; then + # Get on with it + sudo systemctl reboot +# If we don't want to reboot now +elif [[ -v noreboot ]]; then + echo "Next boot set." + exit 0 +# If things are otherwise fucked +else + echo "E: You shouldn't be here..." + exit 1 +fi