Menggunakan perintah `select` untuk mencetak menu di Bash

10

Saya mencoba menerapkan menu sederhana menggunakan selectperintah. Script (untuk tujuan pengujian) adalah sebagai berikut:

#!/bin/bash
echo "*******************"
PS3='Select an option and press Enter: '
options=("apache" "named" "sendmail")
select opt in "${options[@]}"
do
  case $opt in
        "apache")
          date
          ;;
        "named")
          echo "test"
          ;;
        "sendmail")
          echo "test 2"
          ;;
        *) echo "invalid option";;
  esac
done
echo "*********************"

Skrip tidak mengenali input valid apa pun yang saya berikan dan selalu mencetak pesan "opsi tidak valid". Apa yang salah dalam skrip ini?

Sumod
sumber
4
Masukan Anda adalah 1, 2 atau 3, kan?
enzotib

Jawaban:

11

Menu Anda yang ditunjukkan oleh pilih akan terlihat seperti:

1) apache
2) named
3) sendmail
Select an option and press Enter: 

Saat ini, Anda memasukkan "1" atau "2" atau "3": Anda tidak mengetik kata.

Juga, selectakan mengulang sampai melihat breakperintah, jadi Anda menginginkan ini:

  case $opt in
        "apache")
          date
          break
          ;;
        "named")
          echo "test"
          break
          ;;
        "sendmail")
          echo "test 2"
          break
          ;;
        *) echo "invalid option";;
  esac

Jika Anda ingin mengizinkan pengguna memasukkan nomor atau kata, Anda dapat menulis ini:

select opt in "${options[@]}"; do
  case "$opt,$REPLY" in
    apache,*|*,apache)     do_something; break ;;
    named,*|*,named)       do_something; break ;;
    sendmail,*|*,sendmail) do_something; break ;;
  esac
done

Koma tidak memiliki signifikansi sintaksis, hanya ada di sana untuk dapat mencocokkan pola pada variabel $ REPLY (yang merupakan apa yang sebenarnya diketik pengguna) atau variabel $ opt

glenn jackman
sumber
The selectperintah membutuhkan break, tidak case.
glenn jackman
Terima kasih! Saya tidak menyadari bahwa itu adalah pilihan numerik. Duhh!
Sumod
Hah, saya juga memprogram dalam C dan, Anda perlu breakada di setiap bagian. Namun, Anda tidak akan pernah perlu breakdalam kasus ... esac blok dalam shell script . Itu bisa terjadi dengan mudah untuk membuat mereka bingung. :-)
syntaxerror
1
@syntaxerror, Anda benar, Anda tidak perlu breakmelakukannya case. Namun, Anda perlu breakkeluar dari selectloop.
glenn jackman
@glenn jackman Saya ingin ini berubah menjadi komentar yang lebih bermanfaat (lihat selanjutnya). Jadi alangkah baiknya jika Anda setuju menghapus komentar Anda dari 12:55. Saya akan melakukan hal yang sama dengan milik saya, tentu saja.
syntaxerror
3

$optVariabel Anda akan diatur ke kata opsi yang sesuai dengan angka yang dimasukkan pengguna. Jika Anda ingin melihat apa yang sebenarnya diketik pengguna, lihat $REPLY.

Kusalananda
sumber
1
Mengingat bahwa casemembandingkan $optterhadap "apache", "bernama" dan "sendmail", itu benar dan tidak ada yang harus diubah.
manatwork
@manatwork, kecuali OP ingin pengguna mengetikkan kata "apache", "bernama" atau "sendmail" daripada menekan 1, 2 atau 3.
Kusalananda
Menarik. $ REPLY memegang 1/ 2/ 3, dan $ opt apachenamedsendmail
hold
@ Fred, ya, $REPLYadalah apa pun yang diketik pengguna, dan jika itu nomor yang valid maka $optakan menjadi kata yang sesuai dengan nomor itu.
Kusalananda