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-o
e-a
operatori come argomenti per iltest
o[
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.