Tecnica classica (escape metacaratteri):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
Ho racchiuso i riferimenti $g
tra virgolette doppie; questa è una buona pratica, in generale. In senso stretto, le parentesi non sono necessarie perché la precedenza -a
e la -o
rende corretta anche senza di esse.
Si noti che gli operatori -a
e -o
fanno parte delle specifiche POSIX per test
, alias [
, principalmente per la compatibilità con le versioni precedenti (dal momento che facevano parte della test
7a Edizione UNIX, ad esempio), ma sono esplicitamente contrassegnati come "obsoleti" da POSIX. Bash (vedi espressioni condizionali ) sembra anticipare i significati classici e POSIX per -a
e -o
con i suoi operatori alternativi che accettano argomenti.
Con un po 'di attenzione, puoi utilizzare l' [[
operatore più moderno , ma tieni presente che le versioni in Bash e Korn Shell (ad esempio) non devono essere identiche.
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
Esempio di esecuzione, utilizzando Bash 3.2.57 su 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
Non è necessario citare le variabili [[
come si fa [
perché non è un comando separato allo stesso modo [
.
Non è una domanda classica?
Lo avrei pensato. Tuttavia, esiste un'altra alternativa, vale a dire:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
In effetti, se leggi le linee guida della "shell portatile" per lo autoconf
strumento o i relativi pacchetti, questa notazione - usando ' ||
' e ' &&
' - è ciò che raccomandano. Suppongo che potresti persino arrivare a:
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
Dove le azioni sono banali come l'eco, questo non è male. Quando il blocco di azioni da ripetere è composto da più righe, la ripetizione è troppo dolorosa ed è preferibile una delle versioni precedenti oppure è necessario racchiudere le azioni in una funzione richiamata nei diversi then
blocchi.
test
([
) e non dalla shell. La shell valuta solo lo stato di uscita di[
.