Apenas casos simples podem ser expressos com && e || . A construção if é mais geral. if CONDITION; then FOO; fi é equivalente a CONDITION && FOO (assumindo o uso adequado de chaves para delimitar um bloco, se necessário), mas assim que houver um else (ou elif ), isso não será mais possível em geral.
if CONDITION; then FOO; else BAR; fi
não é equivalente a
CONDITION && FOO || BAR
Se CONDITION for true, ambas as construções executam FOO . Se FOO for falso, a construção if ignorará BAR , enquanto a construção && … || executará BAR .
E não, você não pode contornar isso com CONDITION && { FOO; true; } || BAR . Isso faz com que o comando composto retorne verdadeiro se CONDITION for true e FOO for falso, enquanto if CONDITION; then FOO; else BAR; fi retornará falso nesse caso.
Isso é para a diferença semântica. Além disso, há legibilidade: os usos aninhados de && e || tornam-se muito difíceis de decifrar rapidamente. Eu não recomendo usar ambos no mesmo comando, na verdade - especialmente considerando que os dois operadores têm igual precedência no shell, enquanto eles têm precedências diferentes em C e na maioria das outras linguagens inspiradas em C (incluindo Perl e Ruby). / p>