Estou trabalhando com o Bash 3 e estou tentando formar um condicional. Em C / C ++, é muito simples: ((A || B) && C). No Bash, não é bem assim (acho que os autores do Git devem ter contribuído com este código antes de seguirem para outros empreendimentos). 
 Isso não funciona. Observe que <0 or 1> não é uma string literal; significa 0 ou 1 (geralmente vem de grep -i). 
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi 
Isso resulta em:
line 322: syntax error near unexpected token `[[" 
Então tentei:
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi 
resultou em:
line 322: syntax error near unexpected token `[[" 
Parte do problema é que os resultados da pesquisa são os exemplos triviais, e não os exemplos mais complexos com condicionais compostos.
 Como faço um ((A || B) && C) no Bash? 
Estou pronto para simplesmente desenrolar e repetir os mesmos comandos em vários blocos:
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then ... elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then ... fi 
Resposta
A sintaxe do bash não é semelhante a C, mesmo que uma pequena parte dela seja inspirada em C. Você não pode simplesmente tentar escrever código C e esperar que funcione.
 O ponto principal de um shell é executar comandos. O comando de colchetes [ é um comando que realiza 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" ] 
isso “é 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 colchetes não balanceados? Sim, isso não é bom. Sua tentativa com parênteses tem o mesmo problema: colchetes falsos.
A sintaxe para agrupar comandos são colchetes. A maneira como os colchetes são analisados requer um comando completo antes deles, então você precisará terminar o comando dentro dos colchetes com uma nova linha ou ponto e vírgula.
if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then … 
 Lá É uma forma alternativa de usar colchetes duplos. Ao contrário dos colchetes simples, os colchetes duplos são uma sintaxe especial de 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 uma sintaxe de shell, o shell sabe que, quando esses operadores estão entre colchetes, eles “fazem parte da sintaxe da expressão condicional, não fazem parte da sintaxe de comando do shell comum. 
if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then … 
Se todos os seus testes forem numéricos, há ainda outra maneira, que delimita expressões arti-méticas . Expressões aritméticas realizam cálculos inteiros com uma sintaxe muito parecida com C.
if (((A == 0 || B != 0) && C == 0)); then … 
Você pode encontrar meu colchete bash primer útil.
 [ pode ser usado em sh. [[ e (( são específicos para bash (e ksh e zsh). 
¹ Também pode combine vários testes com operadores booleanos, mas isso é complicado de usar e tem armadilhas sutis, então não vou explicar.
Comentários
Resposta
 Use [[: 
if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ... 
 Se você preferir [, o seguinte funciona: 
if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ... 
Comentários
- Obrigado, Stephen. No meu caso, usei seu primeiro exemplo desta forma … regex = ' ^ [0-9] + $ ' length = $ {#datearg} if! [[$ datearg = ~ $ regex & & $ length -eq 8]]; então echo " erro: Não é um número de lenth de 8 "; fi
 
Resposta
 Use o operador -o em vez do seu aninhado ||. Você também pode usar -a para substituir & & se necessário em suas outras declarações . 
 EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true if [ "$A" -eq "0" -o "$B" -ne "0" ] && [ "$C" -eq "0" ]; then echo success;fi 
Comentários
-  Obrigado. Encontrei 
-ae-o, mas não experimentei. Alguém no Stack Overflow disse para evitá-lo. Eu concordo principalmente com eles, pois o script é menos legível com eles. - … mas mais portável.
 -  @Kusalananda – Obrigado pelo aviso sobre portabilidade. O script deve ser executado em sistemas com Bash 2 a Bash 4. 
[[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]terá problemas com eles? -  Não haverá problemas, contanto que você 
bashou qualquer outro shell que compreenda[[ ... ]]. - A desvantagem de usar -a é que não ' t curto-circuito se a primeira expressão for falsa. Portanto, se você depende do curto-circuito para evitar a execução de uma segunda expressão potencialmente fatal, não poderá usar -a. Exemplo: pastebin.com/zM77TXW1
 
[[ … ]]foi adicionado no bash 2.02.((…))foi adicionado ao bash 2.0.||e&&mude de[para[[e((. Igualdade de precedência em[(use parênteses para controlar a ordem de avaliação), mas & & tem maior precedência em[[e((do que||(como em C).[[ … ]]ou$((…))são apenas para agrupamento.