Sto cercando di capire come funziona la precedenza dell'operatore logico in bash. Ad esempio, mi sarei aspettato che il comando seguente non echeggiasse nulla.
true || echo aaa && echo bbb
Tuttavia, contrariamente alle mie aspettative, bbb viene stampato.
Qualcuno può spiegare, come posso dare un senso a && composti e || operatori in bash?
Risposta accettata:
In molti linguaggi informatici, gli operatori con la stessa precedenza sono associativi a sinistra. Cioè, in assenza di strutture di raggruppamento, le operazioni più a sinistra vengono eseguite per prime. Bash non fa eccezione a questa regola.
Questo è importante perché, in Bash, && e || hanno la stessa precedenza.
Quindi quello che succede nel tuo esempio è che l'operazione più a sinistra (|| ) viene eseguita prima:
true || echo aaa
Poiché true è ovviamente vero, il || operatore cortocircuita e l'intera affermazione è considerata vera senza la necessità di valutare echo aaa come ti aspetteresti. Ora resta da fare l'operazione più a destra:
(...) && echo bbb
Poiché la prima operazione è stata valutata come true (cioè aveva uno stato di uscita 0), è come se stessi eseguendo
true && echo bbb
quindi il && non andrà in cortocircuito, motivo per cui vedi bbb fece eco.
Avresti lo stesso comportamento con
false && echo aaa || echo bbb
Note basate sui commenti
- Dovresti notare che la regola dell'associatività a sinistra è solo seguito quando entrambi gli operatori hanno lo stesso precedenza. Questo non è il caso quando utilizzi questi operatori insieme a parole chiave come
[[...]]o((...))oppure usa il-oe-aoperatori come argomenti per iltesto[comandi. In questi casi, AND (&&o-a) ha la precedenza su OR (||o-o). Grazie al commento di Stephane Chazelas per aver chiarito questo punto. -
Sembra che nei linguaggi simili a C e C
&&ha una precedenza maggiore di||questo è probabilmente il motivo per cui ti aspettavi che il tuo costrutto originale si comportasse cometrue || (echo aaa && echo bbb).Questo non è il caso di Bash, tuttavia, in cui entrambi gli operatori hanno la stessa precedenza, motivo per cui Bash analizza la tua espressione usando la regola dell'associatività a sinistra. Grazie al commento di Kevin per averlo sollevato.
-
Potrebbero esserci anche casi in cui tutti e 3 le espressioni vengono valutate. Se il primo comando restituisce uno stato di uscita diverso da zero, il
||non andrà in cortocircuito e prosegue con l'esecuzione del secondo comando. Se il secondo comando ritorna con uno stato di uscita zero, allora&&non andrà in cortocircuito e verrà eseguito il terzo comando. Grazie al commento di Ignacio Vazquez-Abrams per averlo sollevato.