techniką klasyczną (ucieczki metaznaki):
if [ \("$g" -eq 1 -a "$c" = "123" \) -o \("$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
mam zamknięte odniesień do $g
w cudzysłów; to ogólnie dobra praktyka. Ściśle rzecz ujmując, nawiasy nie są potrzebne, ponieważ pierwszeństwo daje im poprawność nawet bez nich.
Zauważ, że operatorzy -a
i -o
są częścią specyfikacji POSIX dla test
, aka [
, głównie dla kompatybilności wstecznej (ponieważ były one częścią test
w 7th Edition UNIX, na przykład), ale są one wyraźnie oznaczone jako "przestarzałe" według POSIX. Bash (patrz conditional expressions) wydaje się wywłaszać znaczenie klasyczne i POSIX dla -a
i -o
z własnymi alternatywnymi operatorami, które pobierają argumenty.
Z pewną ostrożnością, można użyć bardziej nowoczesny operator [[
, ale należy pamiętać, że wersje w bash i Korn Shell (na przykład) nie muszą być identyczne.
for g in 1 2 3
do
for c in 123 456 789
do
if [[ ("$g" -eq 1 && "$c" = "123") || ("$g" -eq 2 && "$c" = "456") ]]
then echo "g = $g; c = $c; true"
else echo "g = $g; c = $c; false"
fi
done
done
Przykład prowadzony przy użyciu Bash 3.2.57 w systemie Mac OS X:
g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false
Nie trzeba zacytować zmienne w [[
jak to zrobić z [
, ponieważ nie jest odrębną polecenia w taki sam sposób, jak [
.
Czy nie jest to klasyczne pytanie?
Tak bym pomyślał. Jednakże, nie ma innej alternatywy, mianowicie:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
Rzeczywiście, jeśli czytasz wytycznymi "przenośny Shell dla narzędzia autoconf
lub z nimi związanych, w tym notacji - używając„||
”oraz„&&
”- to co oni polecić. Przypuszczam, że możesz nawet posunąć się do tego, że:
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
Tam, gdzie działania są tak trywialne jak echo, nie jest to złe. Gdy blok akcji do powtórzenia jest wielokrotny, powtórzenie jest zbyt bolesne i preferowana jest jedna z wcześniejszych wersji - lub musisz zawinąć akcje w funkcję, która jest wywoływana w różnych blokach then
.
Nie proszą o warunkach powłoki ale [test] (https://de.wikipedia.org/wiki/Test_%28Unix % 29) warunki. Całe wyrażenie w twoim przykładzie jest oceniane przez 'test' (' ['), a nie przez powłokę. Powłoka ocenia jedynie status wyjścia '[. – ceving
Zobacz także http://stackoverflow.com/questions/16203088/multiple-conditions-if-statement-bash-script – tripleee