it-swarm-eu.dev

Wie kann ich ein Auswahlmenü in einem Shell-Skript erstellen?

Ich erstelle ein einfaches Bash-Skript und möchte darin ein Auswahlmenü erstellen, wie folgt:

$./script

echo "Choose your option:"

1) Option 1  
2) Option 2  
3) Option 3  
4) Quit  

Und je nach Wahl des Benutzers möchte ich, dass verschiedene Aktionen ausgeführt werden. Ich bin ein bash-Shell-Scripting-Neuling. Ich habe im Web nach Antworten gesucht, aber nichts wirklich Konkretes gefunden.

129
#!/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

Fügen Sie break Anweisungen hinzu, wo immer Sie die select Schleife zum Beenden benötigen. Wenn kein break ausgeführt wird, wird die Anweisung select wiederholt und das Menü erneut angezeigt.

In der dritten Option habe ich Variablen eingefügt, die mit der Anweisung select festgelegt wurden, um zu demonstrieren, dass Sie Zugriff auf diese Werte haben. Wenn Sie es auswählen, wird Folgendes ausgegeben:

you chose choice 3 which is Option 3

Sie können sehen, dass $REPLY die Zeichenfolge enthält, die Sie bei der Eingabeaufforderung eingegeben haben. Es wird als Index für das Array ${options[@]} verwendet, als ob das Array 1-basiert wäre. Die Variable $opt enthält die Zeichenfolge aus diesem Index im Array.

Beachten Sie, dass die Auswahlmöglichkeiten eine einfache Liste direkt in der select -Anweisung sein können:

select opt in foo bar baz 'multi Word choice'

sie können eine solche Liste jedoch nicht in eine skalare Variable einfügen, da in einer der Auswahlmöglichkeiten Leerzeichen enthalten sind.

Sie können auch File Globbing verwenden, wenn Sie zwischen folgenden Dateien wählen:

select file in *.tar.gz
147

Keine neue Antwort per se, aber da es noch keine akzeptierte Antwort gibt, hier ein paar Tipps und Tricks zur Codierung, sowohl für select als auch für 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

Erwähnenswert:

  • Beide werden wiederholt, bis der Benutzer explizit Beenden (oder Abbrechen für Zenity) wählt. Dies ist ein guter Ansatz für interaktive Skriptmenüs: Nachdem eine Auswahl getroffen und eine Aktion ausgeführt wurde, wird das Menü erneut für eine andere Auswahl angezeigt. Wenn die Auswahl nur einmal getroffen werden soll, verwenden Sie einfach break nach esac (der Zenity-Ansatz könnte ebenfalls weiter reduziert werden).

  • Beide case basieren nicht auf Werten, sondern auf Indizes. Ich denke, das ist einfacher zu programmieren und zu warten

  • Array wird auch für den zenity -Ansatz verwendet.

  • Die Option "Beenden" gehört nicht zu den ursprünglichen Optionen. Es wird bei Bedarf "hinzugefügt", damit Ihr Array sauber bleibt. Schließlich ist "Beenden" für Zenity sowieso nicht erforderlich. Der Benutzer kann einfach auf "Abbrechen" klicken (oder das Fenster schließen), um das Programm zu beenden. Beachten Sie, dass beide das gleiche, unberührte Optionsfeld verwenden.

  • PS3 und REPLY können nicht umbenannt werden. select ist fest codiert, um diese zu verwenden. Alle anderen Variablen im Skript (opt, options, Prompt, title) können beliebige Namen haben, sofern Sie die Anpassungen vornehmen

56
MestreLion

Mit dialog würde der Befehl folgendermaßen aussehen:

dialog --clear --backtitle "Backtitle here" --title "Title here" --menu "Wählen Sie eine der folgenden Optionen:" 15 40 4\
 1 "Option 1"\
 2 "Option 2"\
 3 "Option 3" 

enter image description here

Einfügen in ein Skript:

#!/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
54
Alaa Ali

Mit diesem einfachen Skript können Sie Optionen erstellen

#!/bin/bash 
 echo "Auswahl der Operation ************" 
 echo "1) Operation 1" 
 echo "2) Operation 2 "
 Echo" 3) Operation 3 "
 Echo" 4) Operation 4 " 
lies n case $ n in 1) Echo "Sie haben Option 1 gewählt" ;; 2) Echo "Sie haben Option 2 gewählt" ;; 3) Echo "Sie haben Option 3 gewählt"; 4) Echo "Sie haben Option 4 gewählt"; *) Echo "ungültige Option"; Esac
14
jibin

Ich habe noch eine Option, die eine Mischung dieser Antworten ist, aber das Schöne daran ist, dass Sie nur eine Taste drücken müssen und das Skript dann dank der Leseoption -n fortgesetzt wird. In diesem Beispiel werden Sie aufgefordert, das Skript mit ANS als Variable herunterzufahren, neu zu starten oder einfach zu beenden. Der Benutzer muss nur E, R oder S drücken wird gedrückt, dann wird das Skript beendet.

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
8
HarlemSquirrel

Da dies auf Ubuntu abzielt, sollten Sie das Backend verwenden, für das debconf konfiguriert ist. Sie finden das debconf-Backend heraus mit:

Sudo -s "echo get debconf/frontend | debconf-communicate"

Wenn dort "dialog" steht, wird wahrscheinlich whiptail oder dialog verwendet. Auf Lucid ist es whiptail.

Wenn dies fehlschlägt, verwenden Sie bash "select", wie von Dennis Williamson erklärt.

7
Li Lo
#!/bin/sh 
 show_menu () {
 normal = "Echo"\033 [m "` 
 menu = "Echo"\033 [36m "` #Blau 
 number = "echo"\033 [33m "` #yellow 
 bgred = "echo"\033 [41m "` 
 fgred = "echo"\033 [31m "` 
 printf "\ n $ {menu} *************************************** ******* $ {normal}\n "
 printf" $ {menu} ** $ {number} 1) $ {menu} Dropbox einhängen $ {normal}\n "
 printf "$ {menu} ** $ {number} 2) $ {menu} USB 500 Gig Drive einbinden $ {normal}\n" 
 printf "$ {menu} ** $ {number} 3) $ {menu} Apache neu starten $ {normal}\n "
 printf" $ {menu} ** $ {number} 4) $ {menu} ssh Frost Tomcat Server $ {normal}\n "
 printf "$ {menu} ** $ {number} 5) $ {menu} Einige andere Befehle $ {normal}\n" 
 printf "$ {menu} ********* ************************************ $ {normal}\n "
 printf" Bitte geben Sie eine Menüoption ein und drücken Sie oder $ {fgred} x, um das Menü zu verlassen. $ {Normal} "
 Read opt 
} 
 
 Option_picked () {
 msgcolor = "echo"\033 [01; 31m "` # fett rot 
 normal = "echo"\033 [00; 00m "` # normal weiß 
 message = $ {@: - "$ {normal} Error: Keine Nachricht übergeben"} 
 printf "$ {msgcolor } $ {message} $ {normal}\n "
} 
 
 show_menu 
 löschen, während [$ opt! = ''] 
 mache 
 wenn [$ opt = '']; dann 
 beenden; 
 andernfalls 
 bei $ opt in 
 1) clear; 
 option_picked "Option 1 Picked"; 
 printf "Sudo mount/dev/sdh1/mnt/DropBox /; #The 3 terabyte"; 
 Show_menu; 
; 
 2) clear; 
 Option_picked "Option 2 ausgewählt "; 
 Printf" Sudo mount/dev/sdi1/mnt/usbDrive; #The 500 gig drive "; 
 Show_menu; 
; 
 3) clear; 
 option_picked "Option 3 Picked"; 
 printf "Sudo service Apache2 restart"; 
 show_menu; 
; 
 4) clear; 
 option_picked "Option 4 Picked"; 
 printf "ssh lmesser @ -p 2010"; 
 show_menu; 
; 
 x) exit; 
 ;; 
\n) beenden; 
; 
 *) löschen; 
 option_picked "Wählen Sie eine Option aus das Menü "; 
 show_menu; 
; 
 esac 
 fi 
 done
7
Alex Lucard

Ich habe Zenity verwendet, das in Ubuntu immer vorhanden zu sein scheint, sehr gut funktioniert und viele Funktionen hat. Dies ist eine Skizze eines möglichen Menüs:

#! /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
6
LazyEchidna

Ausgefallene Speisekarte

Probieren Sie es zuerst aus, und besuchen Sie dann meine Seite, um eine detaillierte Beschreibung zu erhalten. Sie benötigen keine externen Bibliotheken oder Programme wie dialog oder 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
5
user360154

Es gibt bereits die gleiche Frage in Serverfehler beantwortet. Die dortige Lösung verwendet whiptail .

2
txwikinger