Comment sortir d'un script bash avec menu et sous-menu
Résolu/FerméLume_56 Messages postés 42 Date d'inscription lundi 1 juin 2020 Statut Membre Dernière intervention 12 novembre 2024 - 3 nov. 2022 à 18:46
- Menu bash
- Menu déroulant excel - Guide
- Windows 11 menu démarrer classique - Guide
- Canon quick menu - Télécharger - Utilitaires
- Réinitialiser menu démarrer windows 10 - Guide
- Activer bluetooth tv samsung menu caché ✓ - Forum TV & Vidéo
12 réponses
Modifié le 20 oct. 2022 à 16:55
Bonjour,
Peux-tu encore simplifier le code de sorte à ce qu'il soit minimal, et indiquer comment l'exécuter pour mettre en évidence ton problème (comportement attendu, comportement observé) ?
Pas besoin de télécharger quoi que ce soit, juste la structure de menu, des echo aux bons endroits.
Bonne chance
20 oct. 2022 à 22:24
Bonsoir,
Merci pour la rapidité apportée à ta réponse !
Je te propose un script plus épuré.
#!/bin/bash # Essai de menu / sous-menu # Sélection - je n'ai laissé que deux options, la première ayant un sous-menu PS3='Faites votre choix: ' options=("Commandes" "Exit") select opt in "${options[@]}" do if [ "$opt" == "Exit" ] ; then break fi case $opt in "Commandes") PS3='Quel choix ?' options=("pwd" "curl" "Quit") select model in "${options[@]}" do case $model in "pwd") echo "pwd va s'afficher'" pwd break ;; "curl") echo "curl va s'afficher" curl ifconfig.co/json break;; "Quit") exit ;; *) echo "invalid option $REPLY";; esac done exit esac done # afficher la date (autre commande pour vérifier la poursuite de l'installation) date +"Aujourd'hui, nous sommes le %A %d %B. Il est %T."
En fait, je désire effectuer un choix (enfin, deux !) , à deux niveaux différents :
- le 1er niveau (menu principal), entre les deux options "Commandes" et "Exit".
- le second, une fois l'option "Commandes" choisie, un autre choix intervient entre "pwd", "curl" et "quit".
Mon objectif est de sélectionner "Commandes" puis "pwd" par ex. pour ensuite voir la commande suivante "date..." s'exécuter.
Lors de l'exécution, le choix "Commandes" "pwd" indique bien le chemin (pwd) comme attendu. Par contre, le programme s'arrête sans exécuter la commande suivante "date...".
Si je sélectionne "Exit" au démarrage, on sort du menu et le programme affiche la commande suivante "date..." (cf. ci-dessous)
1) commandes 2) Exit Faites votre choix: 2 Aujourd'hui, nous sommes le jeudi 20 octobre. Il est 22:08:41. C'est le 293e jour de l'année. ------------------ (program exited with code: 0) Press return to continue
Comme tu as pu le constater, je ne suis pas un pro qui ne maîtrise pas tout. Je me suis inspiré de ce que j'ai pu glaner ici et là.
Merci.
25 oct. 2022 à 15:18
Bonjour,
Pardon pour ma réponse tardive je manque de temps en ce moment. En fait il y a un problème au niveau de la structure de ton algorithme, je t'écris le structure du code en python et te laisse l'adapter en bash.
Code :
#!/usr/bin/env python3 import sys def select(choices): s = None while s not in choices: for choice in choices: print(choice) s = input("type your choice: ") return s def menu(): while True: choice1 = select({"exit", "commande"}) if choice1 == "exit": sys.exit(0) else: while True: choice2 = select({"pwd", "curl", "quit"}) if choice2 == "pwd": print("--> pwd") elif choice2 == "curl": print("--> curl") elif choice2 == "quit": break menu()
break permet d'interrompre la boucle la plus enveloppante. Ici le premier break interrompt donc la première boucle while, et le deuxième break interrompt la 2e boucle while. Ainsi :
- quand on choisit "exit" (première boucle) on interrompt la première boucle while et donc le programme ;
- quand on fait "quit" (deuxième boucle), on interrompt la deuxième boucle et donc on refait un tour dans la première boucle while (ce qui revient à afficher le premier menu).
J'ai de plus défini une fonction select afin que le programme redemande à l'utilisateur de faire son choix si celui-ci n'est pas conforme à l'ensemble des valeurs valides.
Exécution :
(mando@silk) (~) $ python3 toto.py
commande
exit
type your choice: commande
quit
pwd
curl
type your choice: pwd
--> pwd
quit
pwd
curl
type your choice: plop
quit
pwd
curl
type your choice: curl
--> curl
quit
pwd
curl
type your choice: quit
commande
exit
type your choice: exit
Bonne chance
26 oct. 2022 à 07:03
Bonjour,
Merci beaucoup d'avoir consacré une partie de ton temps à répondre à ma question. Je vais étudier le script en détail et l'adapter au mieux.
Bonne journée.
Cordialement.
26 oct. 2022 à 10:03
Parfait, en fait je pense que dans ton cas, ligne 30, si tu remplaces exit par break ça devrait suffire (exit quitte le programme au lieu de quitter la boucle la plus enveloppante). Note par ailleurs que si tu veux suivre exactement le code que je t'ai donné, bash permet de déclarer des fonctions.
Tu peux aussi adapter le script python que je t'ai donné à tes besoins, car c'est un langage bien plus confortable que le bash. Le bash prend surtout son sens quand on veut lancer des commandes plus compliquées.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question26 oct. 2022 à 21:42
Merci pour ces précisions. Je n'ai pas encore eu le temps de regarder attentivement !
Modifié le 27 oct. 2022 à 10:12
Bonjour,
J'ai trouvé le temps de regarder comment écrire ton script en bash, voici à quoi ça peut ressembler :
#!/bin/bash # Define the menu list here PS3="> " select opt in "Commands" "Exit" do if [ "$opt" == "Exit" ] ; then echo "Exit" break fi PS3=">> " select subopt in "pwd" "curl" "Quit" do case "$subopt" in "Quit") echo "Quit" break ;; "pwd") echo "pwd" ;; "curl") echo "curl" ;; esac done PS3="> " done
Pour s'y retrouver, tu noteras que je change à la volée l'apparence de l'invite de commande :
- > pour le menu principal
- >> pour le sous menu
Concernant le premier break : celui qui interrompt la boucle select opt. On arrive donc à la dernière ligne du programme et donc on quitte le script. Comme rien n'est fait après le menu, on aurait aussi pu écrire exit 0, ce qui quitte immédiatement le programme.
Concernant le second break : celui qui interrompt la boucle select subopt. Si on voulait quitter le programme avec cette option, il faudrait le remplacer par exit 0.
Exemple :
1) Commands
2) Exit
> 1
1) pwd
2) curl
3) Quit
>> 1
pwd
>> 1
pwd
>> 2
curl
>> 3
Quit
> 2
Exit
Bonne chance
28 oct. 2022 à 12:57
Merci pour ta démonstration très claire. La difficulté que je rencontre consiste à poursuivre l'exécution des commandes. Si tu regardes bien, je précisais dans mon premier message qu'après le choix effectué, l'exécution devait se poursuivre avec autre commande :
# afficher la date (autre commande pour vérifier la poursuite de l'installation) date +"Aujourd'hui, nous sommes le %A %d %B. Il est %T."
C'est à ce niveau que le programme bloquait. Cette commande n'était lue qu'en cas de sortie de la partie du script traitant du choix.
1) Commands
2) Exit
> 2
Exit
Aujourd'hui, nous sommes le vendredi 28 octobre. Il est 12:55:44.
------------------
(program exited with code: 0)
Press return to continue
J'ignore s'il est possible de traiter cette commande dans le script.
31 oct. 2022 à 14:53
Bonjour,
J'ai résolu la question en adaptant un script trouvé sur le Net proposant menu et sous-menu. Voici une version simplifiée. Si elle peut être utile à certains néophytes comme moi, tant mieux !
Encore merci.
#!/bin/bash # Script avec menu et sous-menu while : do echo " ----- SELECT ----- (1) A (2) B (3) Q = Quitter " read choix_ case $choix in 1) echo " -----sous-menu 1----- 1) A1 2) A2 3) Q = Quitter " read choix sous-menu 1 echo case $choix sous-menu 1 in 1) echo "vous avez sélectionné A1 " commande A1 ;; 2) echo "vous avez sélectionné A2 " commande A2;; 3| Q | q ) echo ; exit 0 ;; *) echo "Erreur saisie sous-menu 1";; esac ;; 2) echo " -----sous-menu 2----- 1) B1 2) B2 3) Q = Quitter " read choix sous-menu 2 echo case $choix sous-menu 2 in 1) echo "vous avez sélectionné B1 " commande B1;; 2) echo "vous avez sélectionné B2 " commande B2;; 3| Q | q ) echo ; exit 0 ;; *) echo "Erreur saisie sous-menu 2";; esac ;; 3) | Q | q ) echo ; exit 0 ;; *) echo "Erreur saisi menu principal" ;; esac done
2 nov. 2022 à 15:06
Bonjour,
Concernant ton message #8, je n'ai pas compris : la commande date s'exécute quand tu rencontres la commande (au même titre que les echo que j'ai mis en exemple), mais j'imagine que tu as depuis contourné le problème. En tout cas l'idée est toujours la même que dans mon message #7 : la manière dont sont imbriqués les sous-menus est reflétée par la manière dont sont imbriqués les select.
Voilà à quoi ça pourrait ressembler :
#!/bin/bash # Define the menu list here PS3="> " select opt in "A" "B" "Exit" do case "$opt" in "Exit") echo "Exit" break ;; "A") PS3=">> " select subopt in "Quit" "A1" "A2" do case "$subopt" in "Quit") echo "Quit" break ;; "A1") echo "A1" ;; "A2") echo "A2" ;; esac done ;; "B") PS3=">> " select subopt in "Quit" "B1" "B2" do case "$subopt" in "Quit") echo "Quit" break ;; "B1") echo "B1" ;; "B2") echo "B2" ;; esac done ;; esac PS3="> " done
Exécution :
(mando@silk) (~) $ bash toto.sh
1) A
2) B
3) Exit
> 1
1) Quit
2) A1
3) A2
A> 3
A2
A> 2
A1
A> 1
Quit
> 2
1) Quit
2) B1
3) B2
B> 2
B1
B> 3
B2
B> 1
Quit
> 3
Exit
Concernant ton message #9, c'est une manière plus basique de faire. Contrairement à celle que je viens de proposer; elle n'utilise pas select, donc elle s'applique à des shells autre que bash.
Bonne chance
3 nov. 2022 à 07:07
Merci. je comprends bien la structure du script. Par contre, je n'ai toujours pas compris comment ajouter une commande pour poursuivre le script une fois le choix effectué.
Pour illustrer mon propos, voici ce qui a motivé mes messages :
Je contribue au développement (porteur d'idées, testeur et accessoirement "codeur !)) de oStorybook.
Ayant découvert un programme de Speech to text (nerd-dictation), j'ai proposé d'intégrer ce logiciel dans oStorybook, non pas pour écrire des livres "à la volée" mais pour faciliter la prise de notes, les remarques, etc. Une précision. Une fois lancé, ce programme tourne en tâche de fond et envoie les mots reconnus dans l'application qui est active (courrier, traitement de texte, console, etc)
A l'occasion, je me suis attelé avec le développeur principal à la réalisation du script pour automatiser l'installation.
Le script d'installation lit et exécute les différentes commandes : définition des répertoires d'installation, dépendances, etc. Viennent ensuite la choix de la langue et du modèle linguistique "léger" ou "complet". C'est cette phase qui me posait problème et que j'ai traitée d'une manière détournée (cf #8) avec car, une fois les choix effectués, le programme ne se poursuivait pas. D'où la simulation avec la commande "date" dans mes messages.
Concrètement, j'ai ajouté la commande "whoami" à la fin de ton dernier script, après Exit. La sortie ne m'a pas étonné, la commande reste ignorée. C'est cette difficulté sûrement très triviale que je voulais résoudre. Et comme je suis curieux de nature...
J'ai finalement trouvé un moyen détourné pour réaliser le script qui fonctionne.
Encore merci pour ta disponibilité.
3 nov. 2022 à 11:49
Par contre, je n'ai toujours pas compris comment ajouter une commande pour poursuivre le script une fois le choix effectué.
Peux-tu clarifier ? Si je reprends le message #10, si tu choisis Exit, comme maintenant j'ai mis un break (au lieu de exit), cela te fait poursuivre le programme ligne 51 (au lieu de quitter le script).
Ayant découvert un programme de Speech to text (nerd-dictation), j'ai proposé d'intégrer ce logiciel dans oStorybook, non pas pour écrire des livres "à la volée" mais pour faciliter la prise de notes, les remarques, etc. Une précision. Une fois lancé, ce programme tourne en tâche de fond et envoie les mots reconnus dans l'application qui est active (courrier, traitement de texte, console, etc)
Pourquoi pas, mais de tels outils existent déjà. Par exemple, dans les hôpitaux, certains docteurs ont une espèce de micro qui leur permettent de remplir les dossiers. Ils dictent également les ponctuations et les retours à la lignes, et font quelques corrections mineures au clavier. Cette page recense quelques outils analogues sous Linux. Peut-être qu'il vaut mieux consacrer son énergie à contribuer à un projet existant (pour l'améliorer) plutôt que re-développer quelque chose qui a déjà été fait, à bon entendeur ;-)
Afin de consacrer un fil de discussion par sujet, si tu veux plus de détails, merci d'ouvrir un nouveau fil de discussion.
Concrètement, j'ai ajouté la commande "whoami" à la fin de ton dernier script, après Exit. La sortie ne m'a pas étonné, la commande reste ignorée. C'est cette difficulté sûrement très triviale que je voulais résoudre. Et comme je suis curieux de nature...
Si tu as bien recopié le script #10 et ajouté ligne 51 la commande whoami, normalement ça fait ce que tu veux.
1) A
2) B
3) Exit
> 3
Exit
mando
Si j'ai mal compris ce que tu veux faire, merci de clarifier.
Bonne chance
Modifié le 3 nov. 2022 à 17:04
Il ne s'agit nullement de ré-développer un programme existant mais de l'adapter, ce qui est bien différent. Le projet nerd-dictation est disponible sur Github. Combien d'utilisateurs de l'outil informatique connaissent ce site et combien seraient capables de récupérer l'archive, de l'installer, d'installer les dépendances et de configurer le fichier linguistique ? C'est ce que nous faisons actuellement pour proposer une fonctionnalité opérationnelle ne nécessitant aucune manipulation de la part des utilisateurs.
C'est également ce qu'a fait Papoteur qui a écrit un GUI pour nerd-dictation, Elograf qui malheureusement ne fonctionne pas sur toutes les distros ( Ubuntu Mate en fait partie).
3 nov. 2022 à 17:52
Ah très bien, je ne connaissais pas mais effectivement si c'est l'adapter, c'est parfait !
Quelques pistes pour le packaging : le projet nerd-dictation dispose d'un setup.py, ce qui signifie que le paquet est plus ou moins prêt à être packagé sur Pypi (tous les OS), en rpm (distributions basées sur redhat) ou en deb (distributions basées sur debian). Si ton projet dépend de nerd-dictation et d'autres projets, tu peux tout à fait faire ton propre paquet avec ses propres dépendances. Pour plus de détails, voir ce tutoriel.
3 nov. 2022 à 18:46
Merci pour ces pistes. Le packaging est à l'état de projet car il reste d'autres points à développer.