Snažím se pochopit, jak funguje priorita logického operátora v bash. Například bych očekával, že následující příkaz nebude nic opakovat.
true || echo aaa && echo bbb
Na rozdíl od mého očekávání však bbb
se vytiskne.
Může mi někdo prosím vysvětlit, jak mohu dát smysl složenému &&
a ||
operátory v bash?
Přijatá odpověď:
V mnoha počítačových jazycích jsou operátory se stejnou prioritou asociativní vlevo. To znamená, že při absenci seskupovacích struktur se nejprve provádějí operace zcela vlevo. Bash není výjimkou z tohoto pravidla.
To je důležité, protože v Bash &&
a ||
mají stejnou přednost.
Ve vašem příkladu se tedy stane, že operace zcela vlevo (||
) se provede jako první:
true || echo aaa
Protože true
je zjevně pravda, ||
zkratuje operátor a celé tvrzení je považováno za pravdivé bez nutnosti vyhodnocovat echo aaa
jak byste očekávali. Nyní zbývá provést operaci zcela vpravo:
(...) && echo bbb
Vzhledem k tomu, že první operace byla vyhodnocena jako true (tj. měla stav ukončení 0), je to jako byste spouštěli
true && echo bbb
takže &&
nezkratuje, což je důvod, proč vidíte bbb
ozvalo se.
Stejné chování byste získali s
false && echo aaa || echo bbb
Poznámky založené na komentářích
- Upozorňujeme, že pravidlo levé asociativnosti je pouze následuje, když oba operátory mají stejné přednost. To není případ, kdy tyto operátory používáte ve spojení s klíčovými slovy jako
[[...]]
nebo((...))
nebo použijte-o
a-a
operátory jako argumenty protest
nebo[
příkazy. V takových případech AND (&&
nebo-a
) má přednost před NEBO (||
nebo-o
). Děkujeme komentáři Stephana Chazelase za objasnění tohoto bodu. -
Zdá se, že v jazycích C a C podobných
&&
má vyšší prioritu než||
což je pravděpodobně důvod, proč jste očekávali, že se váš původní konstrukt bude chovat jakotrue || (echo aaa && echo bbb).
To však není případ Bash, ve kterém mají oba operátory stejnou prioritu, a proto Bash analyzuje váš výraz pomocí pravidla asociativity vlevo. Díky Kevinovu komentáři za to, že to přinesl.
-
Mohou také nastat případy, kdy všechny 3 výrazy se vyhodnocují. Pokud první příkaz vrátí nenulový stav ukončení,
||
nezkratuje a pokračuje ve vykonání druhého příkazu. Pokud se druhý příkaz vrátí s nulovým stavem ukončení, pak&&
nezkratuje a bude proveden třetí příkaz. Díky komentáři Ignacia Vazqueze-Abramse za to, že to přinesl.