制作 Bash `efibootmgr` 菜单条目

问题描述 投票:0回答:1

Bash
中,当我输入命令
efibootmgr
时,输出为:

BootCurrent: 0003
Timeout: 2 seconds
BootOrder: 0011,0000,0001,0013,0014,0015,0004,0003,0016,0017
Boot0000* ThrottleStop UEFI
Boot0001* rEFInd Boot Manager
Boot0003* MX23 LinuX
Boot0004* Windows Boot Manager
etc...

我想用

Menu Entry
中的
Alphabet sequence
制作一个
efibootmgr
,但我还不知道很多linux命令。

有人可以帮助我吗?

我想要这样的输出:

[A] ThrottleStop UEFI
[B] rEFInd Boot Manager
[C] MX23 LinuX
[D] Windows Boot Manager
[E] Setup

然后当我按

A
时,电脑将启动到
ThrottleStop UEFI
。按
B
启动至
rEFInd Boot Manager

更新脚本 学习一些命令后。

脚本工作正常,但看起来不太简单

希望任何人都可以用简单的代码更好地重新编码,而无需重新创建或删除临时文件。

#!/bin/bash
test -f '/tmp/efi.tmp' && rm -f '/tmp/efi.tmp'
set -o nounset; C=0; AZ=( {A..Z} )
#Exclude: "Windows|FDD|PCI|CD|Splash"
sudo efibootmgr        \
| egrep -v "Windows|FDD|PCI|CD|Splash" \
| grep -e '^Boot[0-9]' \
| while read -r IDs Line
do printf '%s [%s] %s\n' "$IDs" "${AZ[C ++]}" "$Line" >> '/tmp/efi.tmp'; done
awk '{print $2,$3,$4,$5,$6}' '/tmp/efi.tmp'
echo '[1] Reboot'
echo '[2] Shutdown'
echo '[3] Exit'
    
read -s -n 1 -p ' Choose: ' ans;
case $ans in
    1) sudo reboot;;
    2) sudo poweroff;;
    3) exit;;
    a|b|c|d|e|f|g)
        ID="$(grep -i -F "[$ans]" '/tmp/efi.tmp' | grep -Eo "[0-9]{4}")"
        sudo efibootmgr -q -n $ID; sudo reboot;;
esac

我还不知道:

  • 如何从变量获取“efibootmgr”ID
  • 如何从变量中获取“a|b|c|d|e|f|g”

EFIBOOTMGR 菜单

最后更新

感谢@Gobu的帮助。

#! /bin/bash
function EFIBoot {
    clear
    FWDefID=$(efibootmgr | grep -e 'BootCurrent:' | awk '{print $2}')
    FWDefDE=$(efibootmgr | grep -e "Boot$FWDefID" | awk '{print $2,$3,$4,$5}')
    border='-------------------------------'
    echo Default Firmware $FWDefDE
    echo $border

    set -o nounset; Count=0
    declare -a Letters=( {A..Z} )
    declare -A Entries=()
    declare -u Answer=
    declare -u Press=

    while read -r BootID Description
    do  Index="${Letters[Count ++]}"
        printf '[%s] %s\n' "$Index" "$Description"
        Entries["$Index"]="${BootID#Boot}"
    done < <(efibootmgr | egrep -v "Windows|FDD|PCI|CD|Splash" \
    | grep -e '^Boot[0-9]\+' | tr -d '*')
    ValidLetters="$(echo "${!Entries[*]}" | tr -d ' ')"
    
    echo $border
    echo '[1] Shutdown   [6] Timeout EFI'
    echo '[2] Reboot     [7] Default EFI'
    echo '[3] Sleep      [8] Add New EFI' 
    echo '[4] Log Out    [9] Delete EFI' 
    echo '[5] Recovery   [0] Modify EFI'     
    echo $border
    
    read -n 1 -p 'Choose: ' Answer
    echo
    case "$Answer" in
        (1) sudo halt || sudo poweroff ;;
        (2) sudo reboot ;;
        (3) sudo pm-suspend || sudo systemctl suspend ;;
        (4) pkill -kill -u "$USER" ;;
        (5) echo 'not available yet' ;;
        (6) TimEFI ;;
        (7) DefEFI ;;
        (8) NewEFI ;;
        (9) RemEFI ;;
        (0) ModEFI ;;
        ([$ValidLetters])
            sudo efibootmgr -q -n "${Entries[$Answer]}"
            sudo reboot ;;
    esac
    EFIBoot
}

function DefEFI {
    read -n 1 -p 'EFI Label(A..Z): ' Press
    case $Press in
    ([$ValidLetters]) sudo efibootmgr -q -o "${Entries[$Press]}"
    esac
}

function TimEFI {
    TimeC=$(efibootmgr | grep 'Time')
    echo "Current $TimeC"
    read -n 1 -p 'Seconds: ' Time
    case $Time in
    ([0-9]) sudo efibootmgr -q -t $Time ;;
    esac
}

function NewEFI {
    ESP=$(sudo fdisk -l | grep -e 'EFI System' | awk '{print $1}')
    Disk=$(echo $ESP | tr -d '[0-9]')
    ESPPartNum=$(echo $ESP | tr -d '/a-z')
    ESPPath='/boot/efi/EFI'
    
    test -d "$ESPPath" && open "$ESPPath"
    echo 'Ex: Des "MXLinux", Loader "/EFI/MX23/grubx64.efi"'
    read -p 'Description: ' Des
    read -p 'Loader: ' Loader
    
    #remove '/boot/efi' if exist
    echo $Loader | grep -e "$ESPPath" && Loader="${Loader//'/boot/efi'/''}"
    if [ -f "/boot/efi/$Loader" ]; then
    sudo efibootmgr -c -L "$Des" -d "$Disk" -p "$ESPPartNum" -l "$Loader"
    fi
}

function RemEFI {
    read -n 1 -p 'Label EFI (A..Z): ' Press
    case $Press in
    ([$ValidLetters]) sudo efibootmgr -b "${Entries[$Press]}" -B ;;
    esac
}

function ModEFI { 
    echo 'not available yet'
}

#######
EFIBoot

输出:

Default Firmware rEFInd
-------------------------------
[A] MX23 LinuX
[B] rEFInd
[C] DisablePROCHOT EFI
[D] Setup
[E] Boot Menu
[F] ATA HDD: ADATA SU650
[G] USB HDD:
-------------------------------
[1] Shutdown   [6] Timeout EFI
[2] Reboot     [7] Default EFI
[3] Sleep      [8] Add New EFI
[4] Log Out    [9] Delete EFI
[5] Recovery   [0] Modify EFI
-------------------------------
Choose: 

bash
1个回答
2
投票

这里有一个建议:

#! /bin/bash

set -o nounset

declare -a Letters=( {A..Z} )

declare -A Entries=()

declare -u Answer

Count=0

while read -r BootID Description
do    Index="${Letters[Count ++]}"
      printf '[%s] %s\n' "$Index" "$Description"
      Entries["$Index"]="${BootID#Boot}"
done < <(efibootmgr | grep -e '^Boot[0-9]\+' | tr -d '*')

printf '%s\n' '[1] Reboot'   \
              '[2] Shutdown' \
              '[3] Exit'

ValidLetters="$(echo "${!Entries[*]}" | tr -d ' ')"

read -n 1 -p "Choose:" Answer

case "$Answer" in
     (1) sudo reboot ;;
     (2) sudo poweroff ;;
     ([$ValidLetters])
         sudo efibootmgr -q -n "${Entries[$Answer]}"
         sudo reboot ;;
     (*) exit ;;
esac
  • declare -a Letters=( {A..Z} )

    Letters 被声明为索引数组
  • declare -A Entries=()

    Entries 是一个关联数组(又名字典)
  • declare -u Answer

    ➥ 设置 转换为大写 属性。当为 Answer 分配一个值时,该值会自动转换为大写。
  • while ... done < <(efibootmgr | grep -e '^Boot[0-9]')

    <(...)
    是一个过程替换结构。命令
    efibootmgr | grep -e '^Boot[0-9]'
    在子 shell 中运行,输出存储到临时文件中,该文件的名称被替换为
    <(...)
  • ${!Entries[*]}

    ${!Dictionary[*]}
    构造被 Dictionary 关联数组的 keys 替换,按随机顺序,用空格分隔(由
    IFS
    变量的第一个字符)。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.