关于bash中选择菜单的问题

关于bash中选择菜单的问题

在您告诉我“已经有大量关于此的指南”之前,请知道我实际上已经制作了一个选择菜单并且它正在运行。

然而有一件事让我抓狂。我目前编码此菜单的方式是这样的:

1) 用户选择一个选项 2) 菜单重新加载 3) 选项旁边有一个星号以表明已被选中。

问题:

每次选择后菜单都会重新加载,用户必须一次选择一个选项。你可以想象这很慢,而且会使终端窗口变得混乱。

我想要的是:

用户应该能够输入 1-4 或 1,4,7 来选择多个选项。

我不想要的是:

Whiptail 或 Dialog。我实际上也做了一个,而且完美无缺。但是,如果可以的话,我宁愿不使用它,或者将其用作后备。我认为不使用它会更方便用户(更不用说更容易看)。

代码:

#                           #
### CSGO Plugin selection ###
#                           #

options=(
         "SurfTimer - 2.02 - Core of this server."
         "AutoFileLoader - Caches all material, model, and sound files for players to download."
         "Chat-Procesor - Chat Processing Plugin"
         "Dynamic - PreReq for many plugins to work properly."
         "FixAngles - Fixes 'wrong angle on material' error that gets spammed in console when using store items"
         "Mapchooser_Extended - Map Vote System. See maplist.cfg/mapcycle.cfg.")
....


menu() {
    echo "Avaliable options:"
    for i in ${!options[@]}; do
        printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
    done
    [[ "$msg" ]] && echo "$msg"; :
}

prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
    [[ "$num" != *[![:digit:]]* ]] &&
    (( num > 0 && num <= ${#options[@]} )) ||
    { msg="Invalid option: $num"; continue; }
    ((num--)); msg="${options[num]} was ${choices[num]:+un}checked"
    [[ "${choices[num]}" ]] && choices[num]="" || choices[num]="+"
done

printf "You selected"; msg=" nothing"
for i in ${!options[@]}; do
    [[ "${choices[i]}" ]] && { printf " %s" "${options[i]}"; msg=""; }
done

答案1

我会按照如下方式进行:

menu() {
    clear
    echo "Available options:"
    for i in ${!options[@]}; do
        printf "%3d%s) %s\n" $((i+1)) "${choices[i]:- }" "${options[i]}"
    done
}

prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
    [[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(\d*)-(\d*)/\1 \2/' <<<"$num"))
    for i in $num; do
      ((i--))
      [[ "${choices[i]}" ]] && choices[i]="" || choices[i]="*"
    done
done

这将测试是否$num包含连字符,并在必要时构建范围,然后简单地循环遍历的内容,$num以便用户可以一次给出多个选项,例如1 2 41-4(但不能是它们的组合!)。clear每次在打印菜单之前,它还会显示终端。

相关内容