it-swarm-eu.dev

Jak mohu vytvořit nabídku výběru ve skriptu Shell?

Vytvářím jednoduchý bash skript a v něm chci vytvořit výběrové menu, například:

$./script

echo "Choose your option:"

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

A podle výběru uživatele chci provést různé akce. Jsem bash Shell skriptující noob, prohledal jsem na webu nějaké odpovědi, ale nedostal jsem nic konkrétního.

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

Přidejte příkazy break kamkoli potřebujete smyčku select. Pokud není proveden break, opakuje se příkaz select a nabídka se znovu zobrazí.

Do třetí možnosti jsem zahrnul proměnné, které jsou nastaveny příkazem select, aby bylo prokázáno, že k těmto hodnotám máte přístup. Pokud si vyberete, bude výstup:

you chose choice 3 which is Option 3

Můžete vidět, že $REPLY obsahuje řetězec, který jste zadali na výzvu. Používá se jako index do pole ${options[@]} jako by pole bylo založeno na 1. Proměnná $opt obsahuje řetězec z tohoto indexu v poli.

Volby mohou být jednoduchým seznamem přímo v příkazu select, jako je tento:

select opt in foo bar baz 'multi Word choice'

ale nemůžete vložit takový seznam do skalární proměnné kvůli mezerám v jedné z možností.

Globping souborů můžete také použít, pokud si vyberete mezi soubory:

select file in *.tar.gz

Při použití dialog by příkaz vypadal takto:

dialog - jaderný - zpětný titul "Backtitle here" - title "Title here" --menu "Vyberte jednu z následujících možností:" 15 40 4\
 1 "Option 1"\
 2 „Možnost 2“\
 3 „Možnost 3“ 

enter image description here

Vložení do skriptu:

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

Ne nová odpověď sama o sobě, ale protože zatím neexistuje žádná přijatá odpověď, zde je několik tipů a triků pro kódování pro výběr i zenitu:

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

Stojí za zmínku:

  • Oba se budou opakovat, dokud si uživatel výslovně nevybere Quit (nebo Cancel pro zenity). Toto je dobrý přístup k interaktivním nabídkám skriptů: po výběru volby a provedení akce se znovu zobrazí nabídka pro jinou volbu. Pokud má být volba určena pouze jednorázově, použijte break za esac (přístup zenity lze dále omezit)

  • Oba case jsou založeny spíše na indexech než na hodnotách. Myslím, že je snazší kódovat a udržovat

  • Pole se také používá pro přístup zenity.

  • Možnost „Konec“ není mezi původními, původními možnostmi. V případě potřeby je „přidán“, takže vaše pole zůstane čisté. Nakonec „Quit“ není pro zenity potřeba, uživatel může ukončit kliknutím na „Cancel“ (nebo zavřít okno). Všimněte si, jak oba používají stejné, nedotčené pole možností.

  • PS3 a REPLY vars lze ne přejmenovat. select je pevně zakódován pro jejich použití. Všechny ostatní proměnné ve skriptu (opt, options, Prompt, title) mohou mít libovolná jména, pokud to provedete

58
MestreLion

Tento jednoduchý skript můžete použít k vytváření možností

#!/bin/bash 
 echo "vyberte operaci ************" 
 echo "1) operace 1" 
 echo "2) operace 2 "
 echo" 3) operace 3 "
 echo" 4) operace 4 " 
přečtěte n případ $ n v 1) echo "Vybrali jste možnost 1" ;; 2) echo "Vybrali jste možnost 2" ;; 3) echo "Vybrali jste možnost 3" ;; 4) echo "Vybrali jste možnost 4" ;; *) Echo "neplatná možnost" ;; Esac
16
jibin

Mám ještě jednu možnost, která je kombinací těchto odpovědí, ale to, co dělá Nice je, že stačí stisknout pouze jednu klávesu a skript pokračuje díky -n možnost čtení. V tomto příkladu vyzýváme k vypnutí, restartu nebo jednoduše opuštění skriptu pomocí ANS jako naší proměnné a uživatel musí pouze stisknout E, R nebo S. Také jsem nastavil výchozí ukončit, takže pokud Enter je stisknut a skript skončí.

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
12
HarlemSquirrel
#!/bin/sh 
 show_menu () {
 normal = `echo"\033 [m "` 
 menu = `echo"\033 [36m "` #Blue 
 number = `echo"\033 [33m "` #yellow 
 bgred = `echo"\033 [41m "` 
 fgred = `echo"\033 [31m "` 
 printf "\ n $ {menu} **************************************** ******* $ {normal}\n "
 printf" $ {menu} ** $ {number} 1) $ {menu} Připojte Dropbox $ {normální}\n "
 printf "$ {menu} ** $ {number} 2) $ {menu} Připojte USB 500 Gig Drive $ {normální}\n" 
 printf "$ {menu} ** $ {number} 3) $ {menu} Restartujte Apache $ {normální}\n "
 printf" $ {menu} ** $ {číslo} 4) $ {menu} ssh Frost Tomcat Server $ {normální}\n "
 printf "$ {menu} ** $ {number} 5) $ {menu} Některé další příkazy $ {normální}\n" 
 printf "$ {menu} ********* ************************************** $ {normal}\n "
 printf" Zadejte prosím volbu nabídky a zadejte nebo $ {fgred} x pro ukončení. $ {Normal} "
 Read opt 
} 
 
 Option_picked () {
 msgcolor = `echo"\033 [01; 31m "` # tučně červená 
 normal = `echo"\033 [00; 00m "` # normální bílá 
 zpráva = $ {@: - "$ {normal} Chyba: Nebyla předána žádná zpráva"} 
 printf "$ {msgcolor } $ {message} $ {normal}\n "
} 
 
 Clear 
 show_menu 
 zatímco [$ opt! = ''] 
 udělejte 
 pokud [$ opt = '']; poté 
 exit; 
 else 
 případ $ 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 Vybráno "; 
 Printf" Sudo mount/dev/sdi1/mnt/usbDrive; # 500gigový disk "; 
 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) exit; 
 ;; 
 *) clear; 
 option_picked "Vyberte možnost z menu "; 
 show_menu; 
 ;; 
 esac 
 fi 
 hotovo
8
Alex Lucard

Protože je to zaměřeno na Ubuntu, měli byste použít cokoli backendu debconf, který je nakonfigurován pro použití. Backendf backend najdete pomocí:

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

Pokud řekne „dialog“, pravděpodobně použije whiptail nebo dialog. U Lucida je to whiptail.

Pokud to selže, použijte bash „select“, jak vysvětluje Dennis Williamson.

7
Li Lo

Bash fantazie menu

Vyzkoušejte to nejprve, pak navštivte mou stránku pro podrobný popis ... Není třeba externích knihoven nebo programů, jako je dialog nebo 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
6
user360154

Použil jsem Zenity, která se v Ubuntu jeví jako vždy, funguje velmi dobře a má mnoho schopností. Toto je náčrt možné nabídky:

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

Stejná otázka již existuje v odpovědi serverfault . Řešení tam používá whiptail .

2
txwikinger