Jeśli chcesz wyrazić następujący test w powłoce (sh):
if ( a == 1 && ( b == 1 || b == 2 )) { ... }
Do tej pory najlepsze, co udało mi się napisać, to:
if [[ $a -eq 1 ]]; then
if [[ $b -eq 1 || $b -eq 2 ]]; then
...
fi
fi
Nie wiem jak połączyć && i || z właściwym pierwszeństwem. Googling nie dał mi żadnej odpowiedzi (tutoriale podają tylko podstawowe przykłady, jeśli takie istnieją)
Jaka jest składnia, aby połączyć te dwa, jeśli w jeden?
ksh
? Wówczas początkowy kod wymagałby tylko jednej pary nawiasów:if (( a == 1 && ( b == 1 || b == 2 ))); then :; fi
Odpowiedzi:
Pamiętaj, że
[[ ]]
nie ma go w Bourne ani POSIXsh
. Aby uzyskać prawdziwąsh
składnię, można to zrobić na kilka sposobów.Używanie tylko jednej
[ ]
parylub Unikanie POSIX
-a
i-o
opcji 11 Jednym z powodów, dla uniknięcia
-a
i-o
jest maksymalna mobilność - nie wszystkietest
lub[
implementacje mogą obsługiwać więcej niż 4 argumenty, co jest dokładnie to, co masz, jeśli łańcuch wyrażeń z-a
i-o
a\( \)
.źródło
/bin/sh
, pisanie go przy użyciu funkcji, których nie ma, jest nieprawidłowesh
. Powinieneś zdawać sobie sprawę, żeksh
to NIE jestsh
, ale raczej nadzbiórsh
. Jeśli zabierzesz swój skrypt,ksh
ale zadeklarowany jako,sh
do systemu, w którymsh
nie ma dowiązania symbolicznegoksh
, może się on zepsuć. Możesz uniknąć tego problemu, upewniając się, że skrypt pasuje do deklaracji./bin/sh
wywoła/bin/sh
. Problem/bin/sh
nie jest akceptowany[[
. Nie możesz użyć[[
ani użyć powłoki, która akceptuje[[
, np.ksh
Jako twój shebang.-a
/-o
nie są obsługiwane przez niektóre implementacje, ale to, że nie jest wiarygodne w przypadku arbitralnych argumentów. Podobnie[ "$a" = "$b" -o "$b" = "$c" ]
mogłoby się nie powieść dla wartości$a
podobnych!
przy wielu[
implementacjach.Wypróbowałem trochę składni i znalazłem to
działa.
źródło
Inne podejście POSIX:
źródło
Właściwy sposób to zrobić za pomocą samego
shell
:Wyjaśnienie:
test
tutaj służy jako nawias i-o
logiczny lub. Jeśli logiczny i wewnątrz „nawiasu” użyłbyś-a
.Więcej na ten temat można znaleźć tutaj
źródło