Pergunta sobre os menus selecionados no bash

1

Antes que você me diga "há toneladas de guias sobre isso" saiba que eu realmente tenho um menu selecionado e está funcionando.

No entanto, há uma coisa que está me deixando louco. A maneira que eu tenho este menu codificado atualmente é o que ocorre:

1) O usuário escolhe uma opção 2) recarregamentos do menu 3) A opção tem um asterisco ao lado para mostrar que está selecionado.

Problema:

O usuário tem que selecionar cada opção, uma de cada vez, após o menu ser recarregado após cada seleção. Como você pode imaginar, isso é lento e torna a janela do terminal confusa.

O que eu quero:

O usuário deve poder digitar 1-4 ou 1,4,7 para selecionar várias opções.

O que eu não quero:

Um Whiptail ou Diálogo. Eu realmente fiz um também e é impecável. No entanto, eu preferiria não usá-lo se eu puder ajudá-lo ou usá-lo como um substituto. Eu acho que seria mais fácil de usar (para não mencionar mais fácil para os olhos) para não usar um.

Código:

#                           #
### 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
    
por Sandman007 11.03.2018 / 21:35

1 resposta

2

Eu faria da seguinte forma:

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*)/ /' <<<"$num"))
    for i in $num; do
      ((i--))
      [[ "${choices[i]}" ]] && choices[i]="" || choices[i]="*"
    done
done

Isso testa se $num contém um hífen e cria o intervalo, se necessário, em seguida, simplesmente faz um loop sobre o conteúdo de $num para que os usuários possam fornecer várias opções de uma vez com, por exemplo, 1 2 4 ou 1-4 (mas não uma combinação desses!). Também clear s o terminal toda vez que o menu é impresso.

    
por dessert 11.03.2018 / 23:48