Je crée un script bash simple et je veux y créer un menu de sélection, comme ceci:
$./script
echo "Choose your option:"
1) Option 1
2) Option 2
3) Option 3
4) Quit
Et selon le choix de l'utilisateur, je souhaite que différentes actions soient exécutées. Je suis un scripteur de scripts bash Shell, j'ai cherché sur le Web des réponses, mais je n'ai rien de concret.
#!/bin/bash
# Bash Menu Script Example
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
Ajoutez des instructions break
chaque fois que vous avez besoin de la boucle select
pour quitter. Si un break
n'est pas exécuté, l'instruction select
est bouclée et le menu est affiché à nouveau.
Dans la troisième option, j'ai inclus les variables définies par l'instruction select
afin de démontrer que vous avez accès à ces valeurs. Si vous le choisissez, il générera:
you chose choice 3 which is Option 3
Vous pouvez constater que $REPLY
contient la chaîne que vous avez entrée à l'invite. Il est utilisé comme index dans le tableau ${options[@]}
comme si le tableau était basé sur 1. La variable $opt
contient la chaîne de cet index dans le tableau.
Notez que les choix peuvent être une simple liste directement dans l'instruction select
, comme ceci:
select opt in foo bar baz 'multi Word choice'
mais vous ne pouvez pas mettre une telle liste dans une variable scalaire à cause des espaces dans l'un des choix.
Vous pouvez également utiliser la suppression de fichier si vous choisissez parmi les fichiers:
select file in *.tar.gz
Pas une nouvelle réponse en soi, mais comme il n'y a pas encore de réponse acceptée, voici quelques astuces et astuces de codage, à la fois pour select et zenity:
title="Select example"
Prompt="Pick an option:"
options=("A" "B" "C")
echo "$title"
PS3="$Prompt "
select opt in "${options[@]}" "Quit"; do
case "$REPLY" in
1 ) echo "You picked $opt which is option $REPLY";;
2 ) echo "You picked $opt which is option $REPLY";;
3 ) echo "You picked $opt which is option $REPLY";;
$(( ${#options[@]}+1 )) ) echo "Goodbye!"; break;;
*) echo "Invalid option. Try another one.";continue;;
esac
done
while opt=$(zenity --title="$title" --text="$Prompt" --list \
--column="Options" "${options[@]}"); do
case "$opt" in
"${options[0]}" ) zenity --info --text="You picked $opt, option 1";;
"${options[1]}" ) zenity --info --text="You picked $opt, option 2";;
"${options[2]}" ) zenity --info --text="You picked $opt, option 3";;
*) zenity --error --text="Invalid option. Try another one.";;
esac
done
À noter:
Les deux vont être en boucle jusqu'à ce que l'utilisateur choisisse explicitement de quitter (ou Annuler pour zenity). C'est une bonne approche pour les menus de script interactifs: après avoir sélectionné un choix et effectué l'action, le menu est présenté à nouveau pour un autre choix. Si choix est censé être unique, utilisez simplement break
après esac
(l’approche de zenity pourrait être davantage réduite également)
case
sont tous deux basés sur l'index plutôt que sur la valeur. Je pense que c'est plus facile à coder et à maintenir
Le tableau est également utilisé pour l'approche zenity
name__.
L'option "Quitter" ne figure pas parmi les options initiales d'origine. Il est "ajouté" si nécessaire, afin que votre tableau reste propre. Après tout, "Quitter" n'est de toute façon pas nécessaire pour zenity, l'utilisateur peut simplement cliquer sur "Annuler" (ou fermer la fenêtre) pour quitter. Remarquez comment les deux utilisent le même tableau d'options intact.
PS3
et REPLY
vars peuvent ne pas être renommés. select
est codé en dur pour les utiliser. Toutes les autres variables du script (opt, options, Prompt, title) peuvent avoir les noms de votre choix, à condition de faire les ajustements.
En utilisant dialog
, la commande ressemblerait à ceci:
dialogue --clear --backtitle "Backtitle here" --title "Title here" --menu "Choisissez l'une des options suivantes:" 15 40 4\ 1 "Option 1"\ 2 "Option 2"\ 3 "Option 3"
En le mettant dans un script:
#!/bin/bash
HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"
OPTIONS=(1 "Option 1"
2 "Option 2"
3 "Option 3")
CHOICE=$(dialog --clear \
--backtitle "$BACKTITLE" \
--title "$TITLE" \
--menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT \
"${OPTIONS[@]}" \
2>&1 >/dev/tty)
clear
case $CHOICE in
1)
echo "You chose Option 1"
;;
2)
echo "You chose Option 2"
;;
3)
echo "You chose Option 3"
;;
esac
Vous pouvez utiliser ce script simple pour créer des options
#!/bin/bash echo "sélectionne l'opération ************" echo "1) opération 1" echo "2) opération 2 " écho" 3) opération 3 " écho" 4) opération 4 "
read n case $ n in 1) echo "Vous avez choisi l'option 1" ;; 2) echo "Vous avez choisi l'option 2" ;; ____.] 3) echo "Vous avez choisi l'option 3" ;; 4) echo "Vous avez choisi l'option 4" ;; *) Echo "option invalide" ;; Esac
Etant donné que ceci est destiné à Ubuntu, vous devez utiliser le backend que debconf est configuré pour utiliser. Vous pouvez trouver le backend de debconf avec:
Sudo -s "echo get debconf/frontend | debconf-communicate"
S'il indique "dialogue", il utilisera probablement whiptail
ou dialog
name__. Sur Lucid, c'est whiptail
name__.
Si cela échoue, utilisez bash "select" comme expliqué par Dennis Williamson.
#!/bin/sh show_menu () { normal = `echo"\033 [m "` menu = `echo"\033 [36m "` #Bleu nombre = `echo"\033 [33m "` #yellow bgred = `echo"\033 [41m "` fgred = "echo"\033 [31m "` printf "\ n $ {menu} ************************************* ******* $ {normal}\n " printf" $ {menu} ** $ {numéro} 1) $ {menu} Monter la boîte déroulante $ {normal}\n " printf "$ {menu} ** $ {numéro} 2) $ {menu} Monter un lecteur USB 500 Go $ {normal}\n" printf "$ {menu} ** $ {numéro} 3) $ {menu} Redémarrez Apache $ {normal}\n " printf" $ {menu} ** $ {numéro} 4) $ {menu} ssh Frost Tomcat Server $ {normal}\n " printf "$ {menu} ** $ {numéro} 5) $ {menu} Quelques autres commandes $ {normal}\n" printf "$ {menu} ********* ************************************ $ {normal}\n " printf" Veuillez entrer une option de menu et entrez ou $ {fgred} x pour quitter. $ {Normal} " Read opt } Option_picked () { msgcolor = `echo"\033 [01; 31m "` # gras rouge normal = `echo"\033 [00; 00m "` # blanc normal message = $ {@: - "$ {normal} Erreur: aucun message n'a été transmis"} printf "$ {msgcolor } $ {message} $ {normal}\n " } effacer show_menu tant que [$ opt! = ''] faire si [$ opt = '']; puis sortie; autre cas $ opter pour 1) effacer; sélectionné par "Option 1 choisie"; printf "Sudo mount/dev/sdh1/mnt/DropBox /; #The 3 terabyte"; Show_menu; ;; 2) effacer; Option_picked "Option 2 Choisi "; Printf" Sudo mount/dev/sdi1/mnt/usbDrive; #Le lecteur 500 Go "; Show_menu; ;; 3) clear; option_picked "Option 3 sélectionnée"; printf "Sudo service Apache2 restart"; show_menu; ;; 4) effacer; option_picked "Option 4 Picked"; printf "ssh lmesser @ -p 2010"; show_menu; ;; x) quitter; ;; \n) exit; ;; *) clear; option_picked "Choisissez une option dans le menu "; show_menu; ;; esac fi terminé
J'ai une autre option qui est un mélange de ces réponses, mais ce qui la rend agréable c'est qu'il suffit d'appuyer sur une touche, puis le script se poursuit grâce à l'option -n
de lecture. Dans cet exemple, nous vous invitons à arrêter, à redémarrer ou simplement à quitter le script en utilisant ANS
comme variable et l'utilisateur doit uniquement appuyer sur E, R ou S. La valeur par défaut est Quitter. Par conséquent, si vous appuyez sur Entrée, la commande le script va sortir.
read -n 1 -p "Would you like to exit, reboot, or shutdown? (E/r/s) " ans;
case $ans in
r|R)
Sudo reboot;;
s|S)
Sudo poweroff;;
*)
exit;;
esac
J'ai utilisé Zenity, qui semble toujours être présent dans Ubuntu, fonctionne très bien et dispose de nombreuses fonctionnalités. Ceci est un croquis d'un menu possible:
#! /bin/bash
selection=$(zenity --list "Option 1" "Option 2" "Option 3" --column="" --text="Text above column(s)" --title="My menu")
case "$selection" in
"Option 1")zenity --info --text="Do something here for No1";;
"Option 2")zenity --info --text="Do something here for No2";;
"Option 3")zenity --info --text="Do something here for No3";;
esac
Menu fantaisie Bash
Essayez-le d'abord, puis visitez ma page pour une description détaillée ... Pas besoin de bibliothèques externes ou de programmes comme dialog ou zenity ...
#/bin/bash
# by oToGamez
# www.pro-toolz.net
E='echo -e';e='echo -en';trap "R;exit" 2
ESC=$( $e "\e")
TPUT(){ $e "\e[${1};${2}H";}
CLEAR(){ $e "\ec";}
CIVIS(){ $e "\e[?25l";}
DRAW(){ $e "\e%@\e(0";}
WRITE(){ $e "\e(B";}
MARK(){ $e "\e[7m";}
UNMARK(){ $e "\e[27m";}
R(){ CLEAR ;stty sane;$e "\ec\e[37;44m\e[J";};
HEAD(){ DRAW
for each in $(seq 1 13);do
$E " x x"
done
WRITE;MARK;TPUT 1 5
$E "BASH SELECTION MENU ";UNMARK;}
i=0; CLEAR; CIVIS;NULL=/dev/null
FOOT(){ MARK;TPUT 13 5
printf "ENTER - SELECT,NEXT ";UNMARK;}
ARROW(){ read -s -n3 key 2>/dev/null >&2
if [[ $key = $ESC[A ]];then echo up;fi
if [[ $key = $ESC[B ]];then echo dn;fi;}
M0(){ TPUT 4 20; $e "Login info";}
M1(){ TPUT 5 20; $e "Network";}
M2(){ TPUT 6 20; $e "Disk";}
M3(){ TPUT 7 20; $e "Routing";}
M4(){ TPUT 8 20; $e "Time";}
M5(){ TPUT 9 20; $e "ABOUT ";}
M6(){ TPUT 10 20; $e "EXIT ";}
LM=6
MENU(){ for each in $(seq 0 $LM);do M${each};done;}
POS(){ if [[ $cur == up ]];then ((i--));fi
if [[ $cur == dn ]];then ((i++));fi
if [[ $i -lt 0 ]];then i=$LM;fi
if [[ $i -gt $LM ]];then i=0;fi;}
REFRESH(){ after=$((i+1)); before=$((i-1))
if [[ $before -lt 0 ]];then before=$LM;fi
if [[ $after -gt $LM ]];then after=0;fi
if [[ $j -lt $i ]];then UNMARK;M$before;else UNMARK;M$after;fi
if [[ $after -eq 0 ]] || [ $before -eq $LM ];then
UNMARK; M$before; M$after;fi;j=$i;UNMARK;M$before;M$after;}
INIT(){ R;HEAD;FOOT;MENU;}
SC(){ REFRESH;MARK;$S;$b;cur=`ARROW`;}
ES(){ MARK;$e "ENTER = main menu ";$b;read;INIT;};INIT
while [[ "$O" != " " ]]; do case $i in
0) S=M0;SC;if [[ $cur == "" ]];then R;$e "\n$(w )\n";ES;fi;;
1) S=M1;SC;if [[ $cur == "" ]];then R;$e "\n$(ifconfig )\n";ES;fi;;
2) S=M2;SC;if [[ $cur == "" ]];then R;$e "\n$(df -h )\n";ES;fi;;
3) S=M3;SC;if [[ $cur == "" ]];then R;$e "\n$(route -n )\n";ES;fi;;
4) S=M4;SC;if [[ $cur == "" ]];then R;$e "\n$(date )\n";ES;fi;;
5) S=M5;SC;if [[ $cur == "" ]];then R;$e "\n$($e by oTo)\n";ES;fi;;
6) S=M6;SC;if [[ $cur == "" ]];then R;exit 0;fi;;
esac;POS;done
Il y a déjà la même question dans serverfault répondu. La solution utilise ici whiptail .