A sintaxe do bash não é semelhante ao C, mesmo que uma pequena parte dele seja inspirada por C. Você não pode simplesmente tentar escrever código C e esperar que ele funcione.
O ponto principal de um shell é executar comandos. O comando de suporte aberto [
é um comando, que executa um único teste¹. Você pode até escrever como test
(sem o colchete de fechamento final). Os operadores ||
e &&
são operadores de shell, eles combinam comandos , não testes.
Então, quando você escreve
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
analisado como
[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]
que é o mesmo que
test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"
Observe os suportes não balanceados? Sim, isso não é bom. Sua tentativa com parênteses tem o mesmo problema: colchetes espúrios.
A sintaxe para agrupar comandos juntos é chaves. A forma como as chaves são analisadas requer um comando completo antes delas, então você precisará terminar o comando dentro das chaves com uma nova linha ou ponto-e-vírgula.
if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …
Existe uma maneira alternativa de usar colchetes duplos. Ao contrário dos parênteses únicos, os parênteses duplos são sintaxe especial do shell. Eles delimitam expressões condicionais . Dentro de colchetes duplos, você pode usar parênteses e operadores como &&
e ||
. Como os colchetes duplos são a sintaxe do shell, o shell sabe que quando esses operadores estão entre parênteses, eles fazem parte da sintaxe da expressão condicional, e não parte da sintaxe comum do comando shell.
if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …
Se todos os seus testes forem numéricos, existe ainda outra maneira, que delimita expressões artísticas . Expressões aritméticas executam cálculos inteiros com uma sintaxe muito semelhante a C.
if (((A == 0 || B != 0) && C == 0)); then …
Você pode encontrar o meu primer de colchetes bash útil.
[
pode ser usado em sh simples. [[
e ((
são específicos de bash (e ksh e zsh).
¹ Ele também pode combinar vários testes com operadores booleanos, mas isso é complicado de usar e tem armadilhas sutis, então não vou explicá-lo.