Jeg prøver at implementere en simpel menu ved hjælp af select
kommando. Scriptet (til testformål) er som følger:
#!/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 "*********************"
Scriptet genkender ikke nogen gyldige input, jeg giver, og udskriver altid meddelelsen “ugyldig mulighed”. Hvad laver forkert i dette script?
Kommentarer
- Din input er 1, 2 eller 3, ikke?
Svar
Din menu, der vises med select, vil se ud:
1) apache 2) named 3) sendmail Select an option and press Enter:
På dette tidspunkt indtaster du ” 1 “eller” 2 “eller” 3 “: du skriver ikke ordet.
Også select
løber, indtil den ser en break
kommando, så du vil have dette:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Hvis du vil tillade brugeren at indtaste enten nummeret eller ordet, du kunne skrive dette:
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
Kommaet har ingen syntaktisk betydning, det er bare der for at være i stand til at matche mønster på enten $ REPLY variabel (hvilket er hvad brugeren faktisk har skrevet) eller $ opt-variablen
Kommentarer
-
select
kommandoen har brug for enbreak
, ikkecase
. - Tak! Jeg var ikke klar over, at det var numeriske muligheder. Duhh!
- Hah, også jeg programmerer i C, og du har brug for en
break
der i hvert afsnit. Du behøver dog aldrig enbreak
i en sag … esac blok i et shell-script . Det kan ske så let at blande dem sammen. 🙂 - @syntaxerror, du ' har ret, du behøver ikke ' t har brug for
break
tilcase
. Du skal dog have enbreak
for at undslippeselect
loop. - @glenn jackman Jeg vil gerne have dette forvandlet til en mere nyttig kommentar (se næste). Så det ville være dejligt, hvis du blev enige om at slette din kommentar fra 12:55. Jeg vil selvfølgelig gøre det samme med min.
Svar
Din $opt
-variablen indstilles til det valgord, der svarer til det nummer som brugeren indtaster. Hvis du vil se på, hvad brugeren faktisk har skrevet, skal du se på $REPLY
.
Kommentarer
- I betragtning af at
case
sammenligner$opt
med " apache ", " med navnet " og " sendmail ", det er korrekt, og intet skal ændres. - @manatwork, medmindre OPen ønsker, at brugeren skal skrive ordene " apache ", " med navnet " eller " sendmail " i stedet for at trykke på 1, 2 eller 3.
- Interessant. $ REPLY holder
1
/2
/3
, og $ opt holderapache
/named
/sendmail
- @fred, ja,
$REPLY
er uanset hvad brugeren skrev, og hvis det var et gyldigt tal, vil$opt
være det ord, der svarer til dette nummer.