Ik probeer een eenvoudig menu te implementeren met behulp van de select
commando. Het script (voor testdoeleinden) is als volgt:
#!/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 "*********************"
Het script herkent geen geldige invoer die ik geef en drukt altijd het bericht “ongeldige optie” af. Wat doe je fout in dit script?
Reacties
- Jouw input is 1, 2 of 3, toch?
Antwoord
Uw menu getoond door select zal er als volgt uitzien:
1) apache 2) named 3) sendmail Select an option and press Enter:
Op dit moment voert u ” 1 “of” 2 “of” 3 “: u typt het woord niet.
Bovendien zal select
doorlopen totdat het een break
commando, dus u wilt dit:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Als u wilt dat de gebruiker het nummer of het woord, je zou dit kunnen schrijven:
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
De komma heeft geen syntactische betekenis, het is er alleen om een patroon te kunnen matchen op ofwel de $ REPLY variabele (wat de gebruiker daadwerkelijk heeft getypt) of de $ opt variabele
Opmerkingen
- De
select
commando heeft eenbreak
nodig, nietcase
. - Bedankt! Ik realiseerde me niet dat het numerieke opties waren. Duhh!
- Hah, ook ik programmeer in C en, je hebt een
break
daar in elke sectie nodig. Je hebt echter nooit eenbreak
nodig in een case … esac blok in een shellscript . Het kan zo gemakkelijk gebeuren om ze door elkaar te halen. 🙂 - @syntaxerror, je hebt ' gelijk, je hebt ' geen voor
case
. Je hebt echter eenbreak
nodig om aan deselect
-lus te ontsnappen. - @glenn jackman Ik zou dit graag willen hebben omgezet in een meer nuttige opmerking (zie volgende). Het zou dus geweldig zijn als u ermee instemt om uw opmerking vanaf 12:55 te verwijderen. Ik zal natuurlijk hetzelfde doen met de mijne.
Antwoord
Jouw $opt
variabele wordt ingesteld op het optiewoord dat overeenkomt met het nummer dat de gebruiker invoert. Als je wilt zien wat de gebruiker daadwerkelijk heeft getypt, kijk dan naar $REPLY
.
Reacties
- Aangezien de
case
$opt
vergelijkt met " apache ", " genaamd " en " sendmail ", het is correct en er hoeft niets veranderd te worden. - @manatwork, tenzij het OP wil dat de gebruiker de woorden " invoert apache ", " genaamd " of " sendmail " in plaats van op 1, 2 of 3 te drukken.
- Interessant. $ REPLY bevat
1
/2
/3
, en $ opt bevatapache
/named
/sendmail
- @fred, ja,
$REPLY
is wat de gebruiker heeft getypt, en als het een geldig nummer was, dan is$opt
het woord dat overeenkomt met dat nummer.