nunca use o operador `-a` ou` -o` com `[`

11

Stéphane Chazelas escreveu:

algumas regras como

  • citar sempre variáveis
  • nunca use o operador -aor -o(use vários [comandos e os operadores &&e ||shell)

Torne [confiável com os shells POSIX.

Por que "nunca use o operador -aou -o"?

Como posso "usar vários [comandos e os operadores &&e ||shell)"?

Tim
fonte

Respostas:

13

Por que "nunca use o operador -aou -o"?

Porque eles podem ser ambíguos e, portanto, não são compatíveis com POSIX :

As extensões XSI que especificam as primárias binárias -a e -o e os operadores '(' e ')' foram marcadas como obsoletas. (Muitas expressões que as utilizam são definidas de forma ambígua pela gramática, dependendo das expressões específicas que estão sendo avaliadas.) Os scripts que usam essas expressões devem ser convertidos para os formulários abaixo. Embora muitas implementações continuem suportando esses formulários obsoletos, os scripts devem ser extremamente cuidadosos ao lidar com as entradas fornecidas pelo usuário que possam ser confundidas com essas e outras primárias e operadores. A menos que o desenvolvedor do aplicativo conheça todos os casos que produzem entrada para o script, chamadas como:

test "$1" -a "$2"

deve ser escrito como:

test "$1" && test "$2"

Como posso "usar vários [comandos e os operadores &&e ||shell)"?

Fazendo vários testes e encadeando-os usando os referidos operadores; por exemplo:

[ 0 -eq 0 -a \( 0 -eq 1 -o 1 -eq 1 \) ]

pode ser reescrito como o equivalente:

[ 0 -eq 0 ] && ([ 0 -eq 1 ] || [ 1 -eq 1 ])

ou melhor:

[ 0 -eq 0 ] && { [ 0 -eq 1 ] || [ 1 -eq 1 ]; }
kos
fonte
obrigado. (1) "os operadores '(' e ')' foram considerados obsoletos". São (e )os operadores que agrupam comandos? Se eles são obsoletos, qual é o seu substituto? (2) Deve test "$1" -a "$2"ser substituído por test "$1" && test "$2", ou por ((test "$1" && test "$2"))? Não precisamos do ((..))?
Tim
@ Tim Veja a atualização. (1) Sim - você pode usar ()e {}como um substituto. (2) o primeiro; (())é usado para expansão aritmética, aqui você deseja testar o status de saída da cadeia de testes; portanto, agrupe os testes em um subshell ()ou no shell atual {}.
kos
Obrigado. Acho que minhas perguntas podem ir além deste post. Então eu os publico em um novo post.
Tim
1
@ Tim A única razão para usar os operadores (e )é quando você está usando -aou -o. Como os últimos são obsoletos, obviamente os primeiros também não são mais necessários.
Barmar 23/03