Próbuję zaimplementować proste menu za pomocą select
polecenie. Skrypt (do celów testowych) wygląda następująco:
#!/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 "*********************"
Skrypt nie rozpoznaje żadnych poprawnych danych wejściowych, które podam i zawsze wyświetla komunikat „nieprawidłowa opcja”. Co robię źle w tym skrypcie?
Komentarze
- Twój wpis to 1, 2 lub 3, prawda?
Odpowiedź
Twoje menu wyświetlane po wybraniu będzie wyglądać następująco:
1) apache 2) named 3) sendmail Select an option and press Enter:
W tym momencie wpisujesz „ 1 ”,„ 2 ”lub„ 3 ”: nie wpisujesz słowa.
Ponadto select
zapętli się, dopóki nie zobaczy break
, więc chcesz tego:
case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac
Jeśli chcesz zezwolić użytkownikowi na wprowadzenie numeru lub słowo, możesz napisać to:
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
Przecinek nie ma znaczenia składniowego, jest tylko po to, aby móc dopasować wzorzec na $ REPLY zmienną (którą faktycznie wpisał użytkownik) lub zmienną $ opt
Komentarze
-
select
polecenie wymagabreak
, a niecase
. - Dzięki! Nie zdawałem sobie sprawy, że to opcje numeryczne. Duhh!
- Hah, ja też programuję w C i potrzebujesz
break
w każdej sekcji. Jednak nigdy nie będziesz potrzebowaćbreak
w bloku case … esac w skrypcie powłoki . Może się tak łatwo pomylić. 🙂 - @syntaxerror, ' masz rację, nie ' nie potrzebujesz
break
dlacase
. Potrzebujesz jednakbreak
, aby wyjść z pętliselect
. - @glenn jackman Chciałbym to mieć przekształcił się w bardziej pomocny komentarz (patrz dalej). Byłoby więc wspaniale, gdybyś zgodził się usunąć swój komentarz z godziny 12:55. Oczywiście zrobię to samo ze swoim.
Odpowiedź
Twój $opt
zostanie ustawiona na słowo opcji odpowiadające liczbie wprowadzonej przez użytkownika. Jeśli chcesz zobaczyć, co faktycznie wpisał użytkownik, spójrz na $REPLY
.
Komentarze
- Biorąc pod uwagę, że
case
porównuje$opt
z " apache ", " o nazwie " i " sendmail ", jest poprawne i nic nie trzeba zmieniać. - @manatwork, chyba że OP chce, aby użytkownik wpisał słowa " apache ", " o nazwie " lub " sendmail " zamiast naciskać 1, 2 lub 3.
- Interesujące. $ REPLY zawiera
1
/2
/3
, a $ opt zawieraapache
/named
/sendmail
- @fred, tak, jest tym, co wpisał użytkownik, a jeśli była to poprawna liczba,
$opt
będzie słowem odpowiadającym tej liczbie.