web-dev-qa-db-fra.com

Question sur certains menus dans bash

Avant de me dire "il y a déjà des tonnes de guides sur ce sujet", sachez que j'ai un menu sélectionné et qu'il fonctionne.

Cependant, il y a une chose qui me rend dingue. La façon dont j'ai ce menu codé actuellement c'est ce qui se passe:

1) L'utilisateur choisit une option 2) Le menu est rechargé 3) L'option est accompagnée d'un astérisque pour indiquer qu'elle est sélectionnée.

Problème:

L'utilisateur doit sélectionner chaque option une à la fois après le rechargement du menu après chaque sélection. Comme vous pouvez l’imaginer, cela est lent et complique la fenêtre de terminal.

Ce que je veux:

L'utilisateur doit pouvoir saisir 1-4 ou 1,4,7 pour sélectionner plusieurs options.

Ce que je ne veux pas:

Un whiptail ou un dialogue. En fait, j'en ai fabriqué un également et il est sans faille. Cependant, je préférerais ne pas l'utiliser si je pouvais l'aider ou l'utiliser comme solution de secours. Je pense que ce serait plus convivial (pour ne pas dire plus facile sur les yeux) de ne pas en utiliser un.

Code:

#                           #
### 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
Sandman007

Je le ferais comme suit:

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

Ceci teste si $num contient un trait d'union et construit la plage si nécessaire, puis boucle simplement sur le contenu de $num de sorte que les utilisateurs puissent donner plusieurs options à la fois avec, par exemple. 1 2 4 ou 1-4 (mais pas une combinaison de ceux-ci!). C'est également clears le terminal à chaque fois avant que le menu ne soit imprimé.

2
dessert