Jag försöker implementera en enkel meny med select
kommando. Skriptet (för teständamål) är som följer:
#!/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 "*********************"
Skriptet känner inte igen några giltiga ingångar jag ger och skriver alltid ut meddelandet ”Ogiltigt alternativ”. Vad gör fel i det här skriptet?
Kommentarer
- Din inmatning är 1, 2 eller 3, eller hur?
Svar
Din meny som visas med select kommer att se ut:
1) apache 2) named 3) sendmail Select an option and press Enter:
För närvarande anger du ” 1 ”eller” 2 ”eller” 3 ”: du skriver inte ordet.
Dessutom kommer select
att slinga tills den ser en break
, så du vill ha det här:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Om du vill tillåta användaren att ange antingen numret eller ordet, du kan skriva detta:
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
Kommat har ingen syntaktisk betydelse, det är bara där för att kunna mönstra matchning på antingen $ REPLY variabel (vilket är vad användaren faktiskt skrev) eller $ opt-variabeln
Kommentarer
-
select
kommandot behöver ettbreak
, intecase
. - Tack! Jag insåg inte att det var numeriska alternativ. Duhh!
- Hah, jag programmerar också i C och du behöver en
break
där i varje avsnitt. Du kommer emellertid aldrig att behöva ettbreak
i ett fall … esac -block i ett skalskript . Det kan hända så lätt att blanda dem ihop. 🙂 - @syntaxerror, du ' har rätt, du behöver ' t behöver
break
förcase
. Du behöver dock enbreak
för att undkommaselect
-slingan. - @glenn jackman Jag skulle vilja ha det här förvandlats till en mer användbar kommentar (se nästa). Så det skulle vara bra om du gick med på att radera din kommentar från 12:55. Jag kommer naturligtvis att göra detsamma med min.
Svar
Din $opt
-variabeln kommer att ställas in till det alternativord som motsvarar numret som användaren matar in. Om du vill titta på vad användaren faktiskt skrev, titta på $REPLY
.
Kommentarer
- Med tanke på att
case
jämför$opt
mot " apache ", " med namnet " och " sendmail ", det är korrekt och ingenting behöver ändras. - @manatwork, såvida inte OP vill att användaren ska skriva in orden " apache ", " med namnet " eller " sendmail " istället för att trycka på 1, 2 eller 3.
- Intressant. $ REPLY innehar
1
/2
/3
, och $ opt hållerapache
/named
/sendmail
- @fred, ja,
$REPLY
är vad användaren skrev, och om det var ett giltigt nummer kommer$opt
att vara det ord som motsvarar det numret.