Ich versuche zu verstehen, wie der Vorrang logischer Operatoren in Bash funktioniert. Zum Beispiel hätte ich erwartet, dass der folgende Befehl nichts zurückgibt.
true || echo aaa && echo bbb
Aber entgegen meiner Erwartung bbb
wird gedruckt.
Kann mir bitte jemand erklären, wie ich zusammengesetzten &&
Sinn machen kann und ||
Operatoren in Bash?
Akzeptierte Antwort:
In vielen Computersprachen sind Operatoren mit gleichem Vorrang linksassoziativ. Das heißt, in Abwesenheit von Gruppierungsstrukturen werden die Operationen ganz links zuerst ausgeführt. Bash ist keine Ausnahme von dieser Regel.
Dies ist wichtig, da in Bash &&
und ||
haben dieselbe Priorität.
In Ihrem Beispiel passiert also, dass die Operation ganz links (||
) wird zuerst ausgeführt:
true || echo aaa
Da true
ist offensichtlich wahr, der ||
Operatorkurzschlüsse und die ganze Aussage wird als wahr angesehen, ohne dass echo aaa
ausgewertet werden muss wie Sie es erwarten würden. Jetzt bleibt nur noch die Operation ganz rechts:
(...) && echo bbb
Da die erste Operation als wahr ausgewertet wurde (d. h. einen Exit-Status von 0 hatte), ist es, als würden Sie ausführen
true && echo bbb
also der &&
nicht kurzschließen, weshalb Sie bbb
sehen Echo.
Sie würden das gleiche Verhalten mit
erhaltenfalse && echo aaa || echo bbb
Notizen basierend auf den Kommentaren
- Sie sollten beachten, dass die Linksassoziativitätsregel nur gilt gefolgt, wenn beide Operatoren dasselbe haben Vorrang. Dies ist nicht der Fall, wenn Sie diese Operatoren in Verbindung mit Schlüsselwörtern wie
[[...]]
verwenden oder((...))
oder verwenden Sie das-o
und-a
Operatoren als Argumente fürtest
oder[
Befehle. In solchen Fällen UND (&&
oder-a
) hat Vorrang vor ODER (||
oder-o
). Danke an den Kommentar von Stephane Chazelas für die Klarstellung dieses Punktes. -
Es scheint, dass in C und C-ähnlichen Sprachen
verhält&&
hat eine höhere Priorität als||
Aus diesem Grund haben Sie wahrscheinlich erwartet, dass sich Ihr ursprüngliches Konstrukt wietrue || (echo aaa && echo bbb).
Bei Bash ist dies jedoch nicht der Fall, hier haben beide Operatoren denselben Vorrang, weshalb Bash Ihren Ausdruck mit der Linksassoziativitätsregel parst. Danke an Kevins Kommentar, dass du das angesprochen hast.
-
Es kann auch Fälle geben, in denen alle 3 Ausdrücke werden ausgewertet. Wenn der erste Befehl einen Exit-Status ungleich Null zurückgibt, wird der
||
keinen Kurzschluss und führt den zweiten Befehl aus. Wenn der zweite Befehl mit einem Null-Exit-Status zurückkehrt, dann wird&&
wird auch nicht kurzgeschlossen und der dritte Befehl wird ausgeführt. Danke an den Kommentar von Ignacio Vazquez-Abrams, der das angesprochen hat.