it-swarm-id.com

Bagaimana saya bisa membuat menu pilih dalam skrip Shell?

Saya membuat skrip bash sederhana dan saya ingin membuat menu pilih di dalamnya, seperti ini:

$./script

echo "Choose your option:"

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

Dan sesuai pilihan pengguna, saya ingin berbagai tindakan dijalankan. Saya noob bash Shell scripting, saya telah mencari di web untuk beberapa jawaban, tetapi tidak ada yang benar-benar konkret.

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

Tambahkan pernyataan break di mana pun Anda membutuhkan loop select untuk keluar. Jika break tidak dilakukan, pernyataan select akan terhenti dan menu ditampilkan kembali.

Dalam opsi ketiga, saya menyertakan variabel yang ditetapkan oleh pernyataan select untuk menunjukkan bahwa Anda memiliki akses ke nilai-nilai itu. Jika Anda memilihnya, itu akan menampilkan:

you chose choice 3 which is Option 3

Anda dapat melihat bahwa $REPLY berisi string yang Anda masukkan di Prompt. Ini digunakan sebagai indeks ke dalam array ${options[@]} seolah-olah array tersebut berbasis 1. Variabel $opt berisi string dari indeks itu dalam array.

Perhatikan bahwa pilihan bisa berupa daftar sederhana langsung di pernyataan select seperti ini:

select opt in foo bar baz 'multi Word choice'

tetapi Anda tidak dapat menempatkan daftar seperti itu dalam variabel skalar karena spasi di salah satu pilihan.

Anda juga dapat menggunakan penggumpalan file jika Anda memilih di antara file-file:

select file in *.tar.gz
137

Bukan jawaban baru per se, tetapi karena belum ada jawaban yang diterima, berikut adalah beberapa tips dan trik pengkodean, untuk pilihan dan kemudahan:

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

Layak disebut:

  • Keduanya akan berulang hingga pengguna secara eksplisit memilih Berhenti (atau Batal untuk zenity). Ini adalah pendekatan yang baik untuk menu skrip interaktif: setelah pilihan dipilih dan tindakan dilakukan, menu disajikan lagi untuk pilihan lain. Jika pilihan hanya dimaksudkan satu kali saja, cukup gunakan break setelah esac (pendekatan zenity dapat dikurangi lebih lanjut juga)

  • Kedua case berbasis indeks, bukan berbasis nilai. Saya pikir ini lebih mudah untuk kode dan pemeliharaan

  • Array juga digunakan untuk pendekatan zenity.

  • Opsi "Berhenti" tidak termasuk di antara opsi awal dan asli. Ini "ditambahkan" saat dibutuhkan, sehingga array Anda tetap bersih. Lagipula, "Berhenti" tidak diperlukan untuk zenity, pengguna cukup mengklik "Batal" (atau tutup jendela) untuk keluar. Perhatikan bagaimana keduanya menggunakan array opsi yang sama dan tak tersentuh.

  • PS3 dan REPLY vars dapat tidak diganti nama. select hardcoded untuk menggunakannya. Semua variabel lain dalam skrip (opt, opsi, Prompt, judul) dapat memiliki nama apa pun yang Anda inginkan, asalkan Anda melakukan penyesuaian

54
MestreLion

Menggunakan dialog , perintahnya akan terlihat seperti ini:

dialog --clear --backtitle "Backtitle di sini" --title "Judul di sini" --menu "Pilih salah satu dari opsi berikut:" 15 40 4\
 1 "Opsi 1"\
 2 "Opsi 2"\
 3 "Opsi 3" 

enter image description here

Menempatkannya dalam skrip:

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

Anda dapat menggunakan skrip sederhana ini untuk membuat opsi

#!/bin/bash 
 echo "pilih operasi ************" 
 echo "1) operasi 1" 
 echo "2) operasi 2 "[.____. gema" 3) operasi 3 "
 gema" 4) operasi 4 " 
baca n case $ n di 1) echo "Anda memilih Opsi 1" ;; 2) echo "Anda memilih Opsi 2" ;; 3) gema "Anda memilih Opsi 3" ;; 4) gema "Anda memilih Opsi 4" ;; *) Gema "opsi tidak valid" ;; Esac
14
jibin

Karena ini ditargetkan pada Ubuntu, Anda harus menggunakan backend debconf apa pun yang dikonfigurasi untuk digunakan. Anda dapat menemukan backend debconf dengan:

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

Jika tertulis "dialog" maka kemungkinan menggunakan whiptail atau dialog. Di Lucid itu whiptail.

Jika gagal, gunakan bash "select" seperti yang dijelaskan oleh Dennis Williamson.

7
Li Lo
#!/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} Pasang dropbox $ {normal}\n "
 printf "$ {menu} ** $ {number} 2) $ {menu} Pasang USB 500 Gig Drive $ {normal}\n" 
 printf "$ {menu} ** $ {number} 3) $ {menu} Restart Apache $ {normal}\n "
 printf" $ {menu} ** $ {number} 4) $ {menu} ssh Frost Tomcat Server $ {normal}\n "
 printf "$ {menu} ** $ {number} 5) $ {menu} Beberapa perintah lain $ {normal}\n" 
 printf "$ {menu} ********* ************************************ $ {normal}\n "
 printf" Silakan masukkan opsi menu dan masukkan atau $ {fgred} x untuk keluar. $ {Normal} "
 Baca opt 
} 
 
 Option_picked () {
 msgcolor = `echo"\033 [01; 31m "` # tebal merah 
 normal = `echo"\033 [00; 00m "` # normal white 
 message = $ {@: - "$ {normal} Kesalahan: Tidak ada pesan yang lewat"} 
 printf "$ {msgcolor } $ {message} $ {normal}\n "
} 
 
 hapus 
 show_menu 
 sementara [$ opt! = ''] 
 lakukan 
 jika [$ opt = '']; lalu 
 keluar; 
 lain 
 case $ opt in 
 1) clear; 
 option_picked "Opsi 1 Dipetik"; 
 printf "Sudo mount/dev/sdh1/mnt/DropBox /; #The 3 terabyte"; 
 Show_menu; 
 ;; 
 2) jelas; 
 Option_picked "Opsi 2 Memilih "; 
 Printf" Sudo mount/dev/sdi1/mnt/usbDrive; #The 500 gig drive "; 
 Show_menu; 
 ;; 
 3) clear; 
 option_picked "Option 3 Picked"; 
 printf "Layanan Sudo Apache2 restart"; 
 show_menu; 
 ;; 
 4) jelas; 
 option_picked "Option 4 Picked"; 
 printf "ssh lmesser @ -p 2010"; 
 show_menu; 
 ;; 
 x) keluar; 
 ;; 
\n) keluar; 
 ;; 
 *) hapus; 
 option_picked "Pilih satu opsi dari menu "; 
 show_menu; 
 ;; 
 esac 
 fi 
 selesai
7
Alex Lucard

Saya memiliki satu opsi lagi yang merupakan campuran dari jawaban-jawaban ini tetapi yang membuatnya bagus adalah Anda hanya perlu menekan satu tombol dan kemudian skrip berlanjut berkat opsi baca -n. Dalam contoh ini, kami diminta untuk mematikan, me-reboot, atau cukup keluar dari skrip menggunakan ANS sebagai variabel kami dan pengguna hanya perlu menekan E, R, atau S. Saya juga mengatur default untuk keluar sehingga jika enter ditekan maka skrip akan keluar.

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

Saya telah menggunakan Zenity, yang sepertinya selalu ada di Ubuntu, berfungsi dengan sangat baik dan memiliki banyak kemampuan. Ini adalah sketsa dari menu yang memungkinkan:

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

Bash menu mewah

Coba dulu, lalu kunjungi halaman saya untuk deskripsi terperinci ... Tidak perlu perpustakaan eksternal atau program seperti dialog atau 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

Sudah ada pertanyaan yang sama di serverfault dijawab. Solusi di sana menggunakan whiptail .

2
txwikinger