Încerc să implementez un meniu simplu folosind select
comanda. Scriptul (în scopul testării) este după cum urmează:
#!/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 "*********************"
Scriptul nu recunoaște nicio intrare validă pe care o dau și tipărește întotdeauna mesajul „opțiune nevalidă”. Ce greșesc în acest scenariu?
Comentarii
- Intrarea dvs. este 1, 2 sau 3, nu?
Răspuns
Meniul dvs. afișat prin selectare va arăta ca:
1) apache 2) named 3) sendmail Select an option and press Enter:
În acest moment, introduceți ” 1 „sau” 2 „sau” 3 „: nu tastați cuvântul.
De asemenea, select
se va bucla până când va vedea un break
, deci doriți acest lucru:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Dacă doriți să permiteți utilizatorului să introducă fie numărul, fie cuvântul, ați putea scrie acest lucru:
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
Virgula nu are nicio semnificație sintactică, este doar acolo pentru a putea să se potrivească modelul fie pe $ REPLY variabilă (care este ceea ce a tastat de fapt utilizatorul) sau variabila $ opt
Comentarii
-
select
comanda are nevoie de unbreak
, nu decase
. - Mulțumesc! Nu mi-am dat seama că sunt opțiuni numerice. Duhh!
- Hah, și eu programez în C și, aveți nevoie de un
break
acolo în fiecare secțiune. Cu toate acestea, nu veți avea nevoie niciodată de unbreak
într-un caz … esac bloc într-un script shell . Se poate întâmpla atât de ușor să le amesteci. 🙂 - @syntaxerror, ai ' dreptate, nu ai ' nu ai nevoie de
break
pentrucase
. Cu toate acestea, aveți nevoie de unbreak
pentru a scăpa de buclaselect
. - @glenn jackman Aș dori să am acest lucru transformat într-un comentariu mai util (vezi următorul). Deci, ar fi minunat dacă ați fi de acord să ștergeți comentariul dvs. de la 12:55 Voi face același lucru cu al meu, desigur.
Răspuns
$opt
variabila va fi setată la cuvântul opțional corespunzător număr introdus de utilizator. Dacă doriți să vedeți ce a scris de fapt utilizatorul, uitați-vă la $REPLY
.
Comentarii
- Având în vedere că
case
compară$opt
cu " apache ", " numit " și " sendmail ", este corect și nu trebuie schimbat nimic. - @manatwork, cu excepția cazului în care OP dorește ca utilizatorul să introducă cuvintele " apache ", " numit " sau " sendmail " mai degrabă decât apăsând 1, 2 sau 3.
- Interesant. $ REPLY deține
1
/2
/3
și $ opt păstreazăapache
/named
/sendmail
- @fred, da, este orice a introdus utilizatorul și, dacă a fost un număr valid, atunci
$opt
va fi cuvântul corespunzător acelui număr.