Słuzy do generowania prostych menu.
Z listy argumentów jest tworzone proste ponumerowane menu, każdej pozycji odpowiada kolejna liczba od 1 wzwyż.
Poniżej menu znajduje się znak zachęty (odpowiada za niego prompt zmiennej systemowej $PS3
)
gdzie wpisujemy cyfrę odpowiadająca wybranej przez nas pozycji w menu.
Jeśli nic nie wpiszemy i wciśniemy ENTER, menu będzie wyświetlone ponownie.
To co wpisaliśmy zachowywane jest w zmiennej REPLY
.
Gdy odczytane zostaje EOF (ang. End Of File)
czyli znak końca pliku (CTRL + D) to select kończy pracę.
Pętla działa dotąd dopóki nie wykonane zostaje polecenie break
lub return.
Podpowiedź
Sama pętla select
nie jest często wykorzystywana w skryptach Bash - ponieważ do większości
skryptów przekazuje się parametry z linii poleceń (bardzo rzadko robi się menu wyboru).
Pętla select
bardzo często występuje w towarzystwie instrukcji case.
Przed dalszą analizą poniższej strony polecam zajrzeć do informacji o instrukcji case.
Składnia
select <zmienna> in <lista> ; do
polecenie
done
Przykład
#!/bin/bash
PS3="+++? "
echo "Co wybierasz?"
select y in X Y Z Quit
do
case $y in
"X") echo "Wybrałeś X" ;;
"Y") echo "Wybrałeś Y" ;;
"Z") echo "Wybrałeś Z" ;;
"Quit") exit ;;
*) echo "Nic nie wybrałeś"
esac
break
done
Najpierw zobaczymy proste ponumerowane menu, składające się z czterech elementów: X
, Y
, Z
i Quit
,
teraz wystarczy tylko wpisać numer inetersującej nas opcji, a resztę zrobi instrukcja case
. Polecenie break
,
które znajduje się w przedostatniej linii skryptu, kończy pracę pętli.
Wynik działania przykładu
Co wybierasz?
1) X
2) Y
3) Z
4) Quit
+++? 1
Wybrałeś X
Podpowiedź
Pętle taką można zostąpić pętlą while
z warunkiem zawsze prawdziwym
Pętla while jest opisana również w tym podreczniku.
PS3="+++? "
while [ 1 -eq 1 ] ; do
echo "What next?"
echo "1) X"
echo "2) Y"
echo "3) Z"
echo "Q) Quit"
echo -n $PS3
read anwser
case "${anwser^^}" in
"1") echo "Wybrałeś X" ;;
"2") echo "Wybrałeś Y" ;;
"3") echo "Wybrałeś Z" ;;
"Q") break ;;
*) echo "Nic nie wybrałeś" ;;
esac
done
Wynik działania przykładu
What next?
1) X
2) Y
3) Z
Q) Quit
+++?1
Wybrałeś X
What next?
1) X
2) Y
3) Z
Q) Quit
+++?Q
Ostrzeżenie
Zwróćmy uwagę na zawartośc polecenia case
, nie ma tam już dobrze nam
znanych literek (X
, Y
, Z
). Są za to numerki 1
, 2
, 3
- pętli select
używa się by uprościć sobie życie.
Praktyczny przykład
Ostrzeżenie
Poniższy skrypt przeznaczony jest dla dystrybucji Slackware wygeneruje menu składające się z listy Window Mangerów, po wybraniu konkretnej pozycji uruchomiony zostanie dany WM.
Oczywiście należy skrypt zmodyfikować pod kątem własnego systemu.
Jeśli komuś odpowiada takie rozwiązanie, wystarczy utworzyć alias: alias startx="~/.ten_skrypt"
i po ponownym zalogowaniu mamy po wpisaniu polecenia startx
menu wyboru Window Managerów.
#!/bin/bash
echo ""
echo "[ JAKI WINDOW MANAGER URUCHOMIĆ? WYBIERZ CYFRĘ Z LISTY: ]"
echo ""
select l in BLACKBOX ENLIGHTENMENT GNOME ICEWM KDE MWM OPENWIN TWM WMAKER WYJŚCIE
do
case "$l" in
"BLACKBOX") cat /etc/X11/xinit/xinitrc.blackbox > ~/.xinitrc; startx $@ ;;
"ENLIGHTENMENT") cat /etc/X11/xinit/xinitrc.e > ~/.xinitrc; startx $@ ;;
"GNOME") cat /etc/X11/xinit/xinitrc.gnome > ~/.xinitrc; startx $@ ;;
"ICEWM") cat /etc/X11/xinit/xinitrc.icewm > ~/.xinitrc; startx $@ ;;
"KDE") cat /etc/X11/xinit/xinitrc.kde > ~/.xinitrc; startx $@ ;;
"MWM") cat /etc/X11/xinit/xinitrc.mwm > ~/.xinitrc; startx $@ ;;
"OPENWIN") cat /etc/X11/xinit/xinitrc.openwin > ~/.xinitrc; startx $@ ;;
"TWM") cat /etc/X11/xinit/xinitrc.twm > ~/.xinitrc; startx $@ ;;
"WMAKER") cat /etc/X11/xinit/xinitrc.wmaker > ~/.xinitrc; startx $@ ;;
"WYJŚCIE") exit ;;
*) startx $@
esac
break
done
Elementy składowe listy w pętli select
, noszą takie same nazwy jak wzorce w instrukcji case
co umożliwia bardzo proste dopasowanie odpowiedzi i wykonanie odpowiednich poleceń.
Opis przykładu
.xinitrc
, kopiując do niego zawartość pliku xinitrc
zoptymalizowanego dla KDE, znajdującego się w katalogu: /etc/X11/xinit/xinitrc.kde
, po czym wykonywane jest polecenie startx
.Podpowiedź
Komentarz odnośnie polecenia startx $@
Zmienna $@
to zmienna specjalna umożliwiająca przekazywanie
do skryptu parametrów (startx
to też skrypt powłoki), dzięki czemu możemy spokojnie stosować wszelkie
parametry np. dwukrotne odpalenie X-ów: startx -- :0
na pierwszej konsoli i startx -- :1
na drugiej.
Gdy nie wpiszemy żadnych parametrów $@
jest pusta.
Podpowiedź
A co się stanie w przypadku gdy podczas wyboru Window Managera podamy większą cyfrę niż tą jaką ma ostatni element menu lub jakiś inny znak?
Uruchomiony zostanie ten WM, który ostatnio odpalaliśmy, odpowiada za to linia *) startx $@
Przykład poniżej powinien wyjaśnić sposób użycia jednej i drugiej instrukcji. Przykład został zmodyfikowany przez tłumacza na lepiej odpowiadający potrzebom tekstu:
#!/bin/bash
echo "***********************"
echo "Jakie zwierzęta lubisz najbardziej?"
select opcja in psy koty szczury zadne
do
case "$opcja" in
psy)
echo "psy.... no fakt, są fajne"
;;
koty)
echo "e, koty są fałszywe..."
;;
szczury)
echo "tak, szczurki są cudowne..."
;;
*)
echo "skoro nie lubisz żadnych zwierząt"
echo "to ja już sobie pójdę"
break;
;;
esac
echo "***********************"
done
Powyższy skrypt dzięki instrukcji select
będzie pozwalał na wybór jednej z opcji, a następnie wyswietli tekst komunikatu odpowadający wybranej opcji.
Dla 4 przypadku (zadne
) została użyta instrukcja break
, która przerywa działanie pętli select
.
Tak więc możliwy jest wielokrotny wybór zwierząt pętla select zakończy się w momencie wyboru zwierzęcia, którego nie ma na liście (zadziała instrukcja break
).
Podpowiedź
Wykonanie instrukcji break powoduje natychmiastowe zaprzestanie wykonywania ciała pętli, a kolejna iteracja pętli nie dochodzi do skutku .