Was Sie geschrieben haben, funktioniert eigentlich fast (es würde funktionieren, wenn alle Variablen Zahlen wären), aber es ist überhaupt keine Redewendung.
(…)
Klammern geben eine Unterschale an . Was in ihnen steckt, ist kein Ausdruck wie in vielen anderen Sprachen. Es ist eine Liste von Befehlen (genau wie außerhalb von Klammern). Diese Befehle werden in einem separaten Unterprozess ausgeführt, sodass Umleitungen, Zuweisungen usw., die in Klammern ausgeführt werden, außerhalb der Klammern keine Auswirkungen haben.
- Mit einem führenden Dollarzeichen,
$(…)
ist ein Befehl Substitution : gibt es einen Befehl in den Klammern, und die Ausgabe des Befehls wird als Teil der Kommandozeile (nach Verlängerung Erweiterungen , es sei denn die Substitution zwischen doppelte Anführungszeichen, aber das ist eine andere Geschichte ) .
{ … }
Klammern sind insofern wie Klammern, als sie Befehle gruppieren, aber sie beeinflussen nur das Parsen, nicht das Gruppieren. Das Programm x=2; { x=4; }; echo $x
druckt 4, während 2 x=2; (x=4); echo $x
gedruckt wird. (Auch geschweifte Klammern erfordern vor dem Schließen Leerzeichen und ein Semikolon, Klammern dagegen nicht. Das ist nur eine Syntax-Eigenart.)
- Mit einem führenden Dollarzeichen
${VAR}
wird eine Parametererweiterung auf den Wert einer Variablen mit möglichen zusätzlichen Transformationen erweitert.
((…))
Doppelte Klammern umgeben eine arithmetische Anweisung , dh eine Berechnung auf ganzen Zahlen, mit einer Syntax, die anderen Programmiersprachen ähnelt. Diese Syntax wird hauptsächlich für Zuweisungen und in Bedingungen verwendet.
- Dieselbe Syntax wird in arithmetischen Ausdrücken verwendet
$((…))
, die auf den ganzzahligen Wert des Ausdrucks erweitert werden.
[[ … ]]
doppelte Klammern umgeben bedingte Ausdrücke . Bedingte Ausdrücke basieren hauptsächlich auf Operatoren , um -n $variable
zu testen, ob eine Variable leer ist, und um -e $file
zu testen, ob eine Datei vorhanden ist. Darüber hinaus gibt es String - Gleichheitsoperator: "$string1" == "$string2"
(Vorsicht , dass die rechte Seite ein Muster, zB [[ $foo == a* ]]
Tests , wenn $foo
beginnt mit a
während [[ $foo == "a*" ]]
Tests , wenn $foo
genau a*
), und die vertrauten !
, &&
und ||
Operatoren für die Negation, Konjunktion und Disjunktion sowie Klammern für die Gruppierung. Beachten Sie, dass Sie benötigen einen Raum um jeden Operator (zB [[ "$x" == "$y" ]]
nicht [[ "$x"=="$y" ]]
), und einen Raum oder einen Charakter wie ;
sowohl innerhalb als auch außerhalb der Klammern (zB [[ -n $foo ]]
nicht[[-n $foo]]
).
[ … ]
Einzelne Klammern sind eine alternative Form von bedingten Ausdrücken mit mehr Macken (aber älter und portabler). Schreibe vorerst keine; Machen Sie sich Sorgen um sie, wenn Sie Skripte finden, die sie enthalten.
Dies ist die idiomatische Art, Ihren Test in Bash zu schreiben:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
Wenn Sie eine Portabilität auf andere Shells benötigen, ist dies der richtige Weg (beachten Sie die zusätzlichen Anführungszeichen und die separaten Sätze von Klammern um jeden einzelnen Test sowie die Verwendung des herkömmlichen =
Operators anstelle der ksh / bash / zsh- ==
Variante):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
Gilles 'SO - hör auf böse zu sein'
quelle
==
den Vergleich von der Zuweisung einer Variablen (die auch ist=
) zu unterscheiden[[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]
starten keinen Unterprozess, obwohl der erste Aufzählungspunkt ausdrücklich sagt: "Was in [Klammern] steht, ist kein Ausdruck wie in vielen anderen Sprachen" - aber es ist sicherlich hier! Das ist wahrscheinlich für den erfahrenen Bash-Zauberer offensichtlich, aber nicht einmal für mich sofort. Die Verwirrung kann entstehen , weil einzelne Klammern können in einer verwendeteif
Aussage, nur nicht in Ausdrücke in doppelten eckigen Klammern.==
ist nicht wirklich "idiomatischer" als=
. Sie haben die gleiche Bedeutung, sind jedoch==
eine ksh-Variante, die auch in bash und zsh verfügbar ist, während sie=
portabel sind. Es gibt keinen wirklichen Vorteil bei der Verwendung==
und es funktioniert nicht in normalem sh.==
innen schreiben[[ … ]]
, wenn Sie möchten, haben aber=
den Vorteil , dass Sie auch darin arbeiten.[ … ]
Ich empfehle daher, sich nicht daran zu gewöhnen,==
überhaupt etwas zu verwenden.sehr nah
sollte arbeiten.
Brechen sie ab
ist ein ganzzahliger Vergleich, bei dem as
ist ein Stringvergleich. Ansonsten gruppiere ich die Vergleiche nur richtig.
Doppelte eckige Klammern begrenzen einen bedingten Ausdruck. Und ich finde, dass das Folgende eine gute Lektüre zu diesem Thema ist: "(IBM) Test entmystifizieren, [, [[, ((und wenn-dann-sonst")
quelle
't1'
ist unnötig, oder? Denn im Gegensatz zu arithmetischen Anweisungen in doppelten Klammern, wot1
eine Variable wäre, istt1
ein bedingter Ausdruck in doppelten Klammern nur eine Literalzeichenfolge. Dh[[ $varB == 't1' ]]
ist genau das gleiche wie[[ $varB == t1 ]]
, oder?Eine sehr tragbare Version (sogar für ältere Bourne-Shell):
Dies hat die zusätzliche Qualität, dass höchstens ein Teilprozess ausgeführt wird (was der Prozess ist
[
), unabhängig vom Schalengeschmack.Ersetzen Sie
=
durch,-eq
wenn Variablen numerische Werte enthalten, z3 -eq 03
ist wahr, aber3 = 03
ist falsch. (Stringvergleich)quelle
Hier ist der Code für die Kurzversion der if-then-else-Anweisung:
Beachten Sie Folgendes:
||
und&&
Operanden innerhalb, wenn Bedingung (dh zwischen runden Klammern) logische Operanden (oder / und) sind||
und&&
Operanden außerhalb, wenn Bedingung dann / sonst bedeutetPraktisch heißt es:
wenn (a = 1 oder b = 2) dann "ok" sonst "nok"
quelle
( ... )
erstellen eine Unterschale. Möglicherweise möchten Sie{ ... }
stattdessen geschweifte Klammern verwenden. Jeder in einer Subshell erstellte Status ist im Aufrufer nicht sichtbar.quelle