[: [ argument... ]
Obliczenie wyrażenia warunkowego.
Jest to synonim dla wbudowanego polecenia "test", ale wymagający, by
ostatnim argumentem był `]' pasujący do początkowego `['.
Polecenie [
jest tym samym co wbudowane polecenie test i działa w sposób identyczny (jest zgodne z POSIX).
- Jest przenośne pomiędzy różnymi powłokami, pozwala na sprawdzenie tylko pojedynczego warunku,
- Nie ma możliwości sprawdzenia wielu warunków wewnątrz polecenia
[]
, do robienia operacji AND i OR należy używać odpowiednio operatorów shell&&
i||
,- Polecenie
[
nie pozwala na wykorzystanie negacji (!
) - negacja musi być użyta poza nawiasami jak zwykła komenda shell,- Operator
==
i!=
są sprawdzeniami łancuchów tekstowych
Polecenie [
bardzo często jest mylone ze słowem kluczowym [[
(co w sumie nie powinno być zaskoczeniem dla nikogo ;-)
…).
- Polecenie
[[
przez długi czas było specyficzne tylko dla powłoki bash (obecnie już wiele innych powłok ma je zaimplementowane np. KSH, ZSH),- Operator
==
i!=
pozwalają na użycie reguł matchowania („Pattern matching”),- Występuje operator
=~
pozwalający na uzywanie wyrażeń regularnych,- Polecenie
[[
pozwala na użycie nawiasów (()
) i operatorów logicznych!
,&&
,||
wewnątrz poecenia - zwiększając czytelność kodu
W systemie plików mamy plik .bashrc
wykorzystamy go do wykonania kilku ćwiczeń.
johny@ThinkPad:~$ ls -al1 .bashrc
-rw-r--r-- 1 johny johny 3771 gru 18 17:42 .bashrc
Informacja
Łączenie warunków
Niepoprawne uzycie polecenia [
(dosyć czesty błąd)
johny@ThinkPad:~$ bash <<\EOF
if [ -e .bashrc && -r .bashrc ] ; then
echo "Istnieje plik .bashrc i masz prawa do jego odczytania";
fi
EOF
bash: line 1: [: missing `]'
Nowy sposób z [[
johny@ThinkPad:~$ bash <<\EOF
if [[ -e .bashrc && -r .bashrc ]] ; then
echo "Istnieje plik .bashrc i masz prawa do jego odczytania";
fi
EOF
Istnieje plik .bashrc i masz prawa do jego odczytania
Stary sposób z [
(bardziej przenośny)
johny@ThinkPad:~$ bash <<\EOF
if [ -e .bashrc ] && [ -r .bashrc ] ; then
echo "Istnieje plik .bashrc i masz prawa do jego odczytania";
fi
EOF
Istnieje plik .bashrc i masz prawa do jego odczytania
Nowy sposób z [[
(choć łączenie warunków jest „po staremu”)
johny@ThinkPad:~$ bash <<\EOF
if [[ -e .bashrc ]] && [[ -r .bashrc ]] ; then
echo "Istnieje plik .bashrc i masz prawa do jego odczytania";
fi
EOF
Istnieje plik .bashrc i masz prawa do jego odczytania
Nowy operator [[
pozwala na porównywanie łancuchów znakowych w bardziej intuicyjny sposób.
Poniższy przykład pokazuje naiwne porównanie:
johny@ThinkPad:~$ bash <<\EOF
answer="yes"
if [ "$answer" = y -o "$answer" = yes ] ; then
echo "Answer is YES"
fi
EOF
Answer is YES
Przykład z użyciem operatora [[
oraz =~
(operator wyrażeń regularnych znany z takich języków jak Perl)
pozwala zrobić to samo znacznie mniejszym nakładem pracy.
Podpowiedź
Jezeli jestes już zaznajomiony z wyrażeniami regularnymi to można nawet „łapać” części dopasowań w zimenną ${BASH_REMATCH}
.
W poniższym przykładzie ${BASH_REMATCH[1]}
będzie zawierał słowo „es”.
johny@ThinkPad:~$ bash <<\EOF
answer="yes"
if [[ $answer =~ ^y(es)?$ ]] ; then
echo "Answer is YES"
fi
EOF
Answer is YES
Operator [[
pozwala w porównaniach na uzycie tzw. globbingu, poniższy przykład to ładnie demonstruje.
johny@ThinkPad:~$ bash <<\EOF
answer="yno"
if [[ $answer = y* ]] ; then
echo "Answer is YES"
fi
EOF
Answer is YES
johny@ThinkPad:~$ bash <<\EOF
answer="YeS"
if [[ $answer = [yY][eE][sS] ]] ; then
echo "Answer is YES"
fi
EOF
Answer is YES
Ostrzeżenie
Należy pamiętać, że rozszerzenia basha takie jak [[
najcześciej nie są kompatybilne z innymi shellami.
Dlatego tak ważne jest by zadeklarować powłokę w której nasz skrypt ma być interpretowany - zobacz użycie shebang.