To, co napisałeś, prawie działa (działałoby, gdyby wszystkie zmienne były liczbami), ale wcale nie jest to idiomatyczne.
(…)
nawiasy oznaczają podpowłokę . To, co jest w nich, nie jest wyrażeniem jak w wielu innych językach. To lista poleceń (podobnie jak poza nawiasami). Te polecenia są wykonywane w osobnym podprocesie, więc żadne przekierowanie, przypisanie itp. Wykonane w nawiasach nie ma wpływu poza nawiasami.
- Z wiodącym znakiem dolara
$(…)
jest podstawienie polecenia : w nawiasach znajduje się polecenie, a dane wyjściowe polecenia są używane jako część wiersza polecenia (po dodatkowych rozwinięciach, chyba że podstawienie występuje między podwójnymi cudzysłowami, ale to inna historia ) .
{ … }
nawiasy klamrowe są jak nawiasy, ponieważ grupują polecenia, ale wpływają tylko na parsowanie, a nie na grupowanie. Program x=2; { x=4; }; echo $x
drukuje 4, podczas gdy x=2; (x=4); echo $x
drukuje 2. (Nawiasy klamrowe wymagają spacji wokół nich i średnika przed zamknięciem, podczas gdy nawiasy nie. To tylko dziwactwo składniowe.)
- Z wiodącym znakiem dolara,
${VAR}
jest rozszerzeniem parametru , rozwijającym się do wartości zmiennej, z możliwymi dodatkowymi przekształceniami.
((…))
podwójne nawiasy otaczają instrukcję arytmetyczną , czyli obliczanie liczb całkowitych, ze składnią podobną do innych języków programowania. Ta składnia jest najczęściej używana do przypisań i warunków.
- Ta sama składnia jest używana w wyrażeniach arytmetycznych
$((…))
, które rozwijają się do wartości całkowitej wyrażenia.
[[ … ]]
podwójne nawiasy otaczają wyrażenia warunkowe . Wyrażenia warunkowe są w większości oparte na operatorach, takich jak -n $variable
testowanie, czy zmienna jest pusta i -e $file
testowanie, czy plik istnieje. Istnieją również operatory równości łańcuchów: "$string1" == "$string2"
(uważaj, że prawa strona jest wzorcem, np. [[ $foo == a* ]]
Testy, jeśli $foo
zaczyna się od, a
a [[ $foo == "a*" ]]
testy, jeśli $foo
jest dokładnie a*
), i znane !
, &&
i ||
operatory dla negacji, koniunkcji i rozłączania, a także nawiasy do grupowania. Należy pamiętać, że trzeba przestrzeń wokół każdego operatora (np [[ "$x" == "$y" ]]
, nie [[ "$x"=="$y" ]]
) i spacji lub znaku podobnego ;
wewnątrz i na zewnątrz uchwytów (np [[ -n $foo ]]
, nie[[-n $foo]]
).
[ … ]
pojedyncze nawiasy kwadratowe są alternatywną formą wyrażeń warunkowych z większą liczbą dziwactw (ale starszych i bardziej przenośnych). Nie pisz na razie żadnych; zacznij się o nich martwić, gdy znajdziesz skrypty, które je zawierają.
Oto idiomatyczny sposób napisania testu w bash:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
Jeśli potrzebujesz przenośności do innych powłok, byłby to sposób (zwróć uwagę na dodatkowe cytowanie i oddzielne zestawy nawiasów wokół każdego pojedynczego testu oraz użycie tradycyjnego =
operatora zamiast ==
wariantu ksh / bash / zsh ):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
Gilles „SO- przestań być zły”
źródło
==
do odróżnienia porównania od przypisania zmiennej (która również jest=
)[[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]
nie rozpoczynają podprocesu, chociaż pierwszy punkt wyraźnie mówi: „To, co jest w [nawiasach], nie jest wyrażeniem jak w wielu innych językach” - ale na pewno już jest! Jest to prawdopodobnie oczywiste dla doświadczonego czarodzieja bashów, ale nawet dla mnie natychmiast. Zamieszanie może powstać, ponieważ w nawiasach można używać pojedynczych nawiasówif
, a nie wyrażeń w nawiasach podwójnych.==
nie jest tak naprawdę „bardziej idiomatyczny” niż=
. Mają to samo znaczenie, ale==
jest wariantem ksh dostępnym również w bash i zsh, natomiast=
jest przenośny. Nie ma naprawdę żadnej korzyści z używania==
i nie działa w zwykłym sh.==
środku[[ … ]]
, jeśli chcesz, ale=
ma tę zaletę, że również pracuje[ … ]
, więc zalecam, aby w ogóle nie przyzwyczajać się do używania==
.bardzo blisko
powinno działać.
rozkładam to
to porównanie liczb całkowitych, gdy as
to porównanie ciągów znaków. w przeciwnym razie po prostu poprawnie grupuję porównania.
Podwójne nawiasy kwadratowe ograniczają wyrażenie warunkowe. I uważam, że poniższe zdanie jest dobrym lektorem na ten temat: „(IBM) Test diagnostyczny, [, [[, ((i jeśli-to-jeszcze”)
źródło
't1'
jest konieczne, prawda? Ponieważ w przeciwieństwie do instrukcji arytmetycznych w podwójnych nawiasach, gdziet1
byłaby zmienna,t1
w wyrażeniu warunkowym w podwójnych nawiasach jest tylko literał. Tj. Czy[[ $varB == 't1' ]]
to dokładnie to samo[[ $varB == t1 ]]
, prawda?Bardzo przenośna wersja (nawet do starszej powłoki Bourne'a):
Ma to dodatkową jakość działania tylko jednego podprocesu (co jest procesem
[
), niezależnie od smaku powłoki.Wymienić
=
z-eq
Jeśli zmienne zawierają wartości liczbowe, np3 -eq 03
to prawda, ale3 = 03
to fałsz. (porównanie ciągów)źródło
Oto kod krótkiej wersji instrukcji if-then-else:
Zwróć uwagę na następujące kwestie:
||
i&&
operandy wewnątrz, jeśli warunek (tj. między okrągłymi nawiasami) są operandami logicznymi (lub / i)||
i&&
operandy na zewnątrz, jeśli warunki oznaczają wtedy / elsePraktycznie stwierdzenie mówi:
jeśli (a = 1 lub b = 2) to „ok” else „nok”
źródło
( ... )
tworzy podpowłokę. Może chcieć użyć nawiasów klamrowych{ ... }
zamiast tego . Każdy stan utworzony w podpowłoce nie będzie widoczny w dzwoniącym.źródło