Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 08/04/2016, à 15:57

GnuTux

Script bash : comment accepter plusieurs choix d'un coup ?

Bonjour,

Pour les besoins d'un script bash a moi, j'aurai besoin a un moment donné de questionner l'utilisateur pour savoir, parmi une liste de 10 logiciels particuliers, lesquels il souhaiterai que le script installe automatiquement.
Bien-sûr je sais gérer sans problème l'installation automatique d'application suivant les choix avec les conditions IF mais ce que je ne sais pas faire c'est prendre en considération plusieurs choix d'un coup (que l'utilisateur rentrera de façon séparé par un espace).

Un exemple (là c'est juste des trucs au hasard pour illustrer) :

La question : Quel logiciel voulez vous parmi cette liste ?
Choix possible :
1 => vlc
2 => chromium
3 => wine
4 => playonlinux
5 => scratch
6 => eclipse

Si l'utilisateur souhaite "vlc", "scratch" et "eclipse", il doit rentrer au moment de la question : 1 5 6
(séparé d'un espace).

Comment faire pour prendre en compte ses 3 choix sur la ligne (détecter les 3 chiffres séparés) ?
(en effet, j'aimerai éviter de poser 10 questions a la suite si il y a 10 logiciels...)

merci d'avance pour votre réponse.


Notre forum d'informatique ici : [url]http://[Spam probable, merci de signaler][/url]
Besoin d'assistance sous Linux ? c'est [url=http://[Spam probable, merci de signaler]/distributions-gnulinux-unix-like]ICI[/url] (raccourci pour vous créer un compte [url=http://[Spam probable, merci de signaler]/register]LÀ[/url])

Hors ligne

#2 Le 08/04/2016, à 16:05

jean-luc5629

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Salut;

Peu être un truc du genre :

read -p "Liste des softs : 1 5 6"  list
for i in $list;do
apt-get install -y $i
done

Hors ligne

#3 Le 08/04/2016, à 16:13

GnuTux

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Ok mais par contre l'utilisateur ne doit pas rentrer le nom du logiciel mais le chiffre correspondant au logiciel.

il faut donc ensuite mettre des conditions d'installation de ce genre :

si 1 dans val alors on install tel logiciel
si 2 dans val alors on install tel autre logiciel
etc...
en prenant en compte tous les chiffres (donc plusieurs installation possible)


Notre forum d'informatique ici : [url]http://[Spam probable, merci de signaler][/url]
Besoin d'assistance sous Linux ? c'est [url=http://[Spam probable, merci de signaler]/distributions-gnulinux-unix-like]ICI[/url] (raccourci pour vous créer un compte [url=http://[Spam probable, merci de signaler]/register]LÀ[/url])

Hors ligne

#4 Le 08/04/2016, à 16:40

jean-luc5629

Re : Script bash : comment accepter plusieurs choix d'un coup ?

echo "1 => vlc"
echo "2 => chromium"
./..
read -p "Liste des softs : 1 3 5" list
for i in $list;do
if [ "$i" = "1"; then apt-get install xxx -y;fi
if [ "$i" = "2"; then apt-get install xxx -y;fi
./...
done

Dernière modification par jean-luc5629 (Le 08/04/2016, à 16:42)

Hors ligne

#5 Le 08/04/2016, à 18:16

serged

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Un case sera judicieux:

# [...]
read -p "Quel soft installer ?" rep
case $rep
1: soft="vlc" ;;
2: soft="chromium" ;;
3: soft=wine ;;
 # [...]
 *) echo "Je n'ai pas compris" ; exit ;;
esac
sudo apt-get install $soft

LinuxMint Vera Cinnamon et d'autres machines en MATE, XFCE... 20.x , 21.x ou 19.x
Tour : Asus F2A55 / AMD A8-5600K APU 3,6GHz / RAM 16Go / Nvidia GeForce GT610 / LM21.1 Cinnamon
Portable : LDLC Mercure MH : Celeron N3450 /RAM 4Go / Intel HD graphics 500 i915 / biboot Win 10 (sur SSD) - LM21.1 MATE (sur HDD)

Hors ligne

#6 Le 08/04/2016, à 20:40

GnuTux

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Merci a toi jean-luc5629, ta solution fonctionne a 1 détail près : tu as oublié de fermer avec un "]" dans la condition, avec cette correction ça fonctionne.

Pour Serged : ce que tu proposes ne fonctionne pas, ça renvoi une erreur mais ce n'est pas grave car la solution proposé par jean-luc5629 fonctionne bien.


Notre forum d'informatique ici : [url]http://[Spam probable, merci de signaler][/url]
Besoin d'assistance sous Linux ? c'est [url=http://[Spam probable, merci de signaler]/distributions-gnulinux-unix-like]ICI[/url] (raccourci pour vous créer un compte [url=http://[Spam probable, merci de signaler]/register]LÀ[/url])

Hors ligne

#7 Le 08/04/2016, à 22:33

jean-luc5629

Re : Script bash : comment accepter plusieurs choix d'un coup ?

GnuTux a écrit :

Merci a toi jean-luc5629, ta solution fonctionne a 1 détail près : tu as oublié de fermer avec un "]" dans la condition, avec cette correction ça fonctionne.
.

Mais bien sur...j'ai tapé ça à la va vite... smile

Hors ligne

#8 Le 09/04/2016, à 00:55

Hizoka

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Salut, voici une version perso de ce que je fais avec de la couleur, multi choix nombre et/ou texte avec possibilité de limiter le nombre de réponse

En esperant que cela puisse servir à d'autres.

FUSHIA="\033[1;35m"
RAZ="\e[m"
BLEUFONCE="\033[1;34m"
VERT="\033[0;32m"
ROUGE="\033[1;31m"

function multiselect
{
# valeur de retour numérique : ${multinum[@]}
# valeur de retour de texte : ${multitxt[@]}
# ${@} : les arguments servant de liste
# PS3 : message à afficher avant le listing
# @@ : élément séparateur, partie de gauche valeur texte et à gauche description ( valeur@@description )
# argument : -[0-9] : limite le nombre de reponse possible

# ATTENTION : La liste commence au chiffre 1 mais les tableaux retournés commencent, eux, à 0 (comme tout tableau)

# Remise au propre des variables
unset multinum multitxt limite num x

# Recherche l'option du nombre de reponse
[[ "${1}" == -[0-9]* ]] && limite="${1/#-}"

# Message informatif apparaissant avant la liste
if [[ ${PS3} && ${limite} ]]
then
    if [[ ${limite} = 1 ]]
    then
        echo -e "${FUSHIA}${PS3}${RAZ} ( ${BLEUFONCE}1 seul choix possible.${RAZ} )\n"
    else
        echo -e "${FUSHIA}${PS3}${RAZ} ( ${BLEUFONCE}${limite} choix possibles.${RAZ} )\n"
    fi

elif [[ ${PS3} && -z ${limite} ]]
then
     echo -e "${FUSHIA}${PS3}${RAZ}\n"

else
    echo
fi

# Affichage de la liste des choix
for x in "${@}"
do
    # En cas de limite, on saute la 1ere valeure qui est le chiffre donné
    if [[ ${limite} && -z ${num} ]]
    then
        num=0

    else
        # Incrémentation du numéro pour la prochaine ligne
        ((num++))

        # recherche le signe servant de séparateur entre la valeur et la description
        if [[ "${x}" =~ "@@" ]]
        then
            # Si séparateur présent : affichage du numéro, de la valeur du texte et de la description
            echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x%%@@*}${RAZ} : ${VERT}${x##*@@}${RAZ}"

        else
            # Si pas de séparateur : affichage du numéro et de la valeur du texte
            echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x}${RAZ}"
        fi
    fi
done

# Envoie de la réponse dans un tableau
read -p $'\nSélection : ' -a multinum

# Création d'une liste contenant les valeurs textes choisies + Vérification des valeurs numériques
for x in "${multinum[@]}"
do
    if [[ ${x} -gt ${#@} || ! ${x} =~ ^[0-9]*$ ]]
    then
        # Message d'erreur indiquant une réponse impossible
        echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres inférieurs à la valeur maximale proposée.${RAZ}"

        # Destruction des variables
        unset multinum multitxt limite

        # Arrêt de la fonction en erreur (code 1)
        return 1

    elif [[ ${limite} && ${#multinum[@]} -gt ${limite} ]]
    then
        # Message d'erreur indiquant un nombre de reponse trop élevé
        echo -e "\n${ROUGE}Nombre de séléction trop importante, la limite est de ${limite} choix.${RAZ}"

        # Destruction des variables
        unset multinum multitxt limite

        # Arrêt de la fonction en erreur (code 1)
        return 1

    else
        # Si il y a eu un argument pour militer le nombre de reponse, on ajoute 1 a x
        [[ "${1}" == -[0-9]* ]] && ((x++))

        # Ajout de la valeur traitée dans le tableau
        multitxt+=("${!x%%@@*}")
    fi
done
}

Exemple d'utilisation :

PS3="Selectionnez les dépots à installer parmis cette liste"
multiselect "Autre@@Ajouter un ppa n'apparraissant pas dans la liste" \
"AntiMicro@@Logiciel de gestion de manettes (Association de touches et de commandes)" \
"Back in time@@Depot Dev du logiciel de sauvegarde Back in time" \
"Chromium@@Derniere version du navigateur Chromium" \
"Handbrake@@Encodeur vidéo" \
"Kubuntu Backport" \
"Oqapy@@Logiciel de téléchargement des vidéos d'Arté" \
"Play On Linux@@Simplifie la gestion de Wine" \
"SABnzbd@@Gestionnaire de newsgroup" \
"Screencastor@@@Mon logiciel de capture vidéo d'écran" \
"Smplayer@@Lecteur vidéo en derniere version" \
"Skrooge@@Gestionnaire de compte bancaire" \
"Virtualbox@@Virtualisation de PC" \
"vlc Stable@@Lecteur vidéo en version plus récente" \
"vlc Dev@@Lecteur vidéo en version Dev" \
"Y PPA Manager@@Gestionnaire de PPA" \
"Zenitor@@@Mon logiciel de créatio de code Zenity" \
"Exit"

echo "multitxt : ${multitxt[@]}"
echo "multinum : ${multinum[@]}"

Avec limite d'un seul choix possible :

multiselect -1 "Changer le nombre de montage avant un check" "Arreter completement les checks" "Exit"

et pour traiter les réponses :

for valeur in "${multitxt[@]}"
do
     case ${valeur} in
        "Autre") ....;;
        "Caca") .....;;
     esac
done

for valeur in "${multinum[@]}"
do
     case ${valeur} in
        "1") ....;;
        "2") .....;;
     esac
done

EDIT : Petit exemple video : http://asciinema.org/a/1jopfdv63194lons3vwl41ln3

Dernière modification par Hizoka (Le 09/04/2016, à 11:02)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#9 Le 09/04/2016, à 08:25

serged

Re : Script bash : comment accepter plusieurs choix d'un coup ?

GnuTux a écrit :

Pour Serged : ce que tu proposes ne fonctionne pas, ça renvoi une erreur mais ce n'est pas grave car la solution proposé par jean-luc5629 fonctionne bien.

J'ai fait ça de tête...
Il faut mettre :

1) soft = vlc ;;
2).... ;;

(mettre des ( à la place des : pour les choix).

Désolé!


LinuxMint Vera Cinnamon et d'autres machines en MATE, XFCE... 20.x , 21.x ou 19.x
Tour : Asus F2A55 / AMD A8-5600K APU 3,6GHz / RAM 16Go / Nvidia GeForce GT610 / LM21.1 Cinnamon
Portable : LDLC Mercure MH : Celeron N3450 /RAM 4Go / Intel HD graphics 500 i915 / biboot Win 10 (sur SSD) - LM21.1 MATE (sur HDD)

Hors ligne

#10 Le 09/04/2016, à 10:59

Hizoka

Re : Script bash : comment accepter plusieurs choix d'un coup ?

serged  => et pas d'espaces entre le =


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#11 Le 03/05/2016, à 11:50

carreti

Re : Script bash : comment accepter plusieurs choix d'un coup ?

Hizoka a écrit :

Salut, voici une version perso de ce que je fais avec de la couleur, multi choix nombre et/ou texte avec possibilité de limiter le nombre de réponse

Hello et un grand merci pour cette réponse, je cherchais depuis quelques jours une solution de choix multiples acceptant un tableau en argument et j'avais déjà lu ta réponse qui m'a beaucoup inspiré, modifiée pour correspondre à mes besoins ...

function makeMultiChoice(){
IFS_SAV=$IFS
IFS='"' read -a ARG_ARRAY <<< ${@}
IFS=$IFS_SAV
NUM=0
echo -e "$Bleu * $PS3"
for X in "${ARG_ARRAY[@]}";do
  ((NUM++))
  if [[ "$X" =~ "@@" ]];then
    NUM_PRINT=$NUM
    # Pour padder à blanc sur 2 positions
    if [ "$(expr length $NUM)" -lt "2" ];then
      NUM_PRINT=" "$NUM
    fi
    echo -e "$Vert $NUM_PRINT) $Jaune${X%%@@*}$Blanc" $Vert : ${X##*@@}"
  else # Nettoyage des lignes vides du tableau et repositionnement du compteur après suppression
    let IDX=NUM-1
    unset ARG_ARRAY[$IDX]
    ((NUM--))
  fi
done
read -p $'\nSélection : ' -a SEL_ARRAY

for X in "${SEL_ARRAY[@]}";do
  if [[ "$X" -gt "${#ARG_ARRAY[@]}" || ! $X =~ ^[0-9]*$ ]];then
    echo -e "$Rouge !!! Sélection incorrecte !!! (valeur saisie : $X)$Blanc"
  else
    let IDX=X-1
    # initialisation et alimentation à la volée tableau résultats
    RESULT_ARR=("${RESULT_ARR[@]}" $(jq -r ". | .[$IDX] | .Url | .[28:40]" <<< $JSON_RESULT))
  fi
done
}

J'ai pris l'habitude (mauvaise ?) d'utiliser du JSON en mémoire comme tableau multidimensionnel dans mes scripts ...
Je formate avec jq le résultat JSON d'une requête pour appeler la fonction "makeMultiChoice", résultat qui est comparé en fin de fonction pour ressortir les données qui m'intéressent du tableau original en fonction des choix faits :

# Mise en forme pour makeMultiChoice
FORMATED_JSON_RESULT=$(jq -r '.[] | " \"\(.Titre)@@\(.Url)\" "' <<< $JSON_RESULT)
PS3="========================\n * Selection des titres à télécharger :\n * ========================"
makeMultiChoice $FORMATED_JSON_RESULT

J'ai encore quelques TODO notamment limiter le nombre de réponses transmises à la fonction par le JSON ou proposer un choix dans une liste alphabétique (dans une boucle dans le main en faisant un autre JSON intermédiaire) et je pourrais certainement optimiser la mise en forme pour l'IFS pour éviter les lignes blanches (") ... Peut-être aussi déplacer la dernière boucle qui est spécifique dans le main du prog (et puis aussi prévoir une sortie, là c'est CTRL+C) et un choix qui prends toutes les sélections. Sinon ça marche déjà comme ça et puis c'est un script qui est appelé par crontab par défaut, l'interactivité est  juste un plus ...

Dernière modification par carreti (Le 03/05/2016, à 15:01)


Utilisateur et administrateur de Linux et d'Unix (depuis le siècle dernier) et plus précisément ces dernières années de  Linux Gentoo et de Windows 10 ...
Je cherche du boulot sur Paris et RP Ouest en administration système ou mieux dans la tierce maintenance applicative, middleware, base de données, flux ...

Hors ligne

#12 Le 04/05/2016, à 08:51

Hizoka

Re : Script bash : comment accepter plusieurs choix d'un coup ?

ravi que cela puisse servir smile


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#13 Le 04/05/2016, à 09:27

MicP

Re : Script bash : comment accepter plusieurs choix d'un coup ?

GnuTux a écrit :

…mais par contre l'utilisateur ne doit pas rentrer le nom du logiciel mais le chiffre correspondant au logiciel.…

Bash : Tableaux associatifs

=======
bash-hackers.org : arrays # associative

=======
Voir aussi la page man du bash :
faire :
man bash
puis entrez :
/associatifs

Dernière modification par MicP (Le 04/05/2016, à 09:36)

Hors ligne

#14 Le 04/05/2016, à 14:11

carreti

Re : Script bash : comment accepter plusieurs choix d'un coup ?

MicP a écrit :

Bash : Tableaux associatifs

=======
bash-hackers.org : arrays # associative

=======
Voir aussi la page man du bash :
faire :
man bash
puis entrez :
/associatifs

Sympa tout ça ... Dans ces conditions est-il possible de faire un tableau de tableaux en bash ? Et sinon, ils n'évoquent pas la suppression d'un enregistrement dans un tableau. J'ai l'impression qu'il y a un trucs pas clair autour de ça. La valeur est effacée mais l'index pas reconstruit dynamiquement (?), mes scripts fonctionnent donc j'ai pas trop cherché ... mais quand j'aurais le temps je testerais plus profondément. En attendant le JSON me convient, et au pire je le dump sur le disque pour déboguer. Par contre jq est très lent comparé à un grep, par exemple. Les tableaux pourraient être plus rapides et il serait facile d'initialiser un tableau associatif à partir de JSON et de le retransformer en JSON en fin d'utilisation pour historisation par exemple, permettant de gagner du temps sur toutes les manipulations intermédiaires éventuelles.
Pas envie de hijacker trop le post de GnuTux wink


Utilisateur et administrateur de Linux et d'Unix (depuis le siècle dernier) et plus précisément ces dernières années de  Linux Gentoo et de Windows 10 ...
Je cherche du boulot sur Paris et RP Ouest en administration système ou mieux dans la tierce maintenance applicative, middleware, base de données, flux ...

Hors ligne

#15 Le 05/05/2016, à 17:15

MicP

Re : Script bash : comment accepter plusieurs choix d'un coup ?

@ carreti

Pour supprimer un tableau comme pour supprimer un de ses élément, il faut utiliser unset

=======
J'ai eu un peu de mal à retrouver le fil de discussion, mais voilà le lien : https://www.debian-fr.org/t/awk-test-si … leau/67562

et un extrait (légèrement modifié) au sujet des "trous" dans les tableaux + quelques liens.

michel@debG53SW:~$ a[1]="Hello";a[3]="World";a[11]="!"  # J'ai un peu poussé la dispersion des éléments du tableau
michel@debG53SW:~$ echo "${!a[@]}"                      # J'affiche la liste des indexs dont les éléments ne sont pas vides
1 3 11
michel@debG53SW:~$ copie=( "${a[@]}" )                  # Je créé un autre tableau par copie du tableau
michel@debG53SW:~$ echo "${!copie[@]}"                  # et je constate qu'il n'y a pas de "trous" dans la copie
0 1 2
michel@debG53SW:~$ echo "${!a[@]}"                      # les "trous" sont encore présents dans le tableau original
1 3 11
michel@debG53SW:~$ a=( "${a[@]}" )                      # Copie du tableau sur lui même pour "faire le ménage"
michel@debG53SW:~$ echo "${!a[@]}"
0 1 2
michel@debG53SW:~$

http://wiki.bash-hackers.org/syntax/arrays
http://abs.traduc.org/abs-fr/ch27.html
http://mywiki.wooledge.org/BashGuide/Arrays

Dernière modification par MicP (Le 05/05/2016, à 17:26)

Hors ligne