Was du geschrieben hast, funktioniert tatsächlich fast (es würde funktionieren, wenn alle Variablen Zahlen wären), aber es ist überhaupt nicht auf idiomatische Weise.
(…)
Klammern zeigen eine Unter-Shell an. Was sich darin befindet, ist kein Ausdruck wie in vielen anderen Sprachen. Es handelt sich um eine Liste von Befehlen (genau wie außerhalb der Klammern). Diese Befehle werden in einem separaten Unterprozess ausgeführt, sodass alle Umleitungen, Zuweisungen usw., die innerhalb der Klammern ausgeführt werden, keine Auswirkungen außerhalb der Klammern haben.
- Mit einem führenden Dollarzeichen ist
$(…)
eine Befehls-Substitution: Es gibt einen Befehl innerhalb der Klammern, und die Ausgabe des Befehls wird als Teil der Befehlszeile verwendet (nach zusätzlichen Erweiterungen, es sei denn, die Substitution befindet sich zwischen doppelten Anführungszeichen, aber das ist eine andere Geschichte).
{ … }
Klammern sind wie Klammern, da sie Befehle gruppieren, aber sie beeinflussen nur die Analyse, nicht die Gruppierung. Das Programm x=2; { x=4; }; echo $x
gibt 4 aus, während x=2; (x=4); echo $x
2 ausgibt. (Außerdem erfordern Klammern Leerzeichen um sie herum und ein Semikolon vor dem Schließen, während Klammern das nicht erfordern. Das ist nur eine Syntax-Eigenheit.)
- Mit einem führenden Dollarzeichen lautet die Syntax
${VAR}
Parameter-Expansion, die den Wert einer Variablen erweitert, mit möglichen zusätzlichen Transformationen.
((…))
doppelte Klammern umgeben eine arithmetische Anweisung, das heißt, eine Berechnung von Ganzzahlen, mit einer Syntax, die anderen Programmiersprachen ähnelt. Diese Syntax wird hauptsächlich für Zuweisungen und Bedingungen verwendet.
- Dieselbe Syntax wird in arithmetischen Ausdrücken
$((…))
verwendet, die den ganzzahligen Wert des Ausdrucks erweitern.
[[ … ]]
doppelte eckige Klammern umgeben Bedingungsausdrücke. Bedingungsausdrücke basieren hauptsächlich auf Operatoren wie -n $variable
zum Testen, ob eine Variable leer ist, und -e $file
zum Testen, ob eine Datei existiert. Es gibt auch Zeichenfolgen-Gleichheitsoperatoren: "$string1" == "$string2"
(beachte, dass die rechte Seite ein Muster ist, z. B. [[ $foo == a* ]]
testet, ob $foo
mit a
beginnt, während [[ $foo == "a*" ]]
testet, ob $foo
genau a*
ist), und die vertrauten !
, &&
und ||
Operatoren zur Negation, Konjunktion und Disjunktion sowie Klammern zur Gruppierung. Beachte, dass du um jeden Operator herum ein Leerzeichen benötigst (z. B. [[ "$x" == "$y" ]]
, nicht [[ "$x"=="$y" ]]
), und ein Leerzeichen oder ein Zeichen wie ;
sowohl innerhalb als auch außerhalb der Klammern benötigst (z. B. [[ -n $foo ]]
, nicht [[-n $foo]]
).
[ … ]
einfache eckige Klammern sind eine alternative Form von Bedingungsausdrücken mit mehr Eigenheiten (aber älter und portabler). Schreibe vorerst keine, fang an, dich darüber Gedanken zu machen, wenn du Skripte findest, die sie enthalten.
Das ist die idiomatische Art, deinen Test in bash zu schreiben:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
Wenn du die Portabilität zu anderen Shells benötigst, wäre dies der Weg:
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
(beachte die zusätzlichen Anführungszeichen und die separaten Klammern um jeden einzelnen Test herum und die Verwendung des traditionellen =
Operators anstelle der ksh/bash/zsh ==
Variante)