Are =, =, , ==,! =, &&, e || usado para expressões aritméticas ou expressões condicionais?

-1

No manual do bash, a Seção 6.5 da Aritmética da Shell diz

<= >= < > comparison
== != equality and inequality 

&& logical AND
|| logical OR

Seus significados parecem implicar que eles são usados para expressões condicionais. Mas eles aparecem na seção para expressões aritméticas.

  1. Então, eles podem ser usados em expressões condicionais ?

    Na Seção 6.4, já temos operadores para condicional expressões, que são semelhantes a <=,>=,<,>,==,!= para aritmética expressões:

    arg1 OP arg2

    OP is one of ‘-eq’, ‘-ne’, ‘-lt’, ‘-le’, ‘-gt’, or ‘-ge’. These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respectively. Arg1 and arg2 may be positive or negative integers.

    Também já temos operadores para expressões condicionais, que são semelhantes a && e || para expressões aritméticas:

    • -a e -o para test , ou seja, [...]
    • && e || para [[...]] .

    Como temos os operadores introduzidos para expressões condicionais, por que precisamos desses operadores similares introduzidos para expressões aritméticas?

  2. Eles podem ser usados em comandos de teste ?

    Sabemos que if é seguido por um comando de teste

    The syntax of the if command is:

    if test-commands; then
    consequent-commands;
    [elif more-test-commands; then
    more-consequents;]
    [else alternate-consequents;]
    fi
    

    [...] e [[...]] recebem expressões condicionais e criam comandos de teste. Eles podem tomar expressões aritméticas?

    O que me deixa confuso é quando [...] e [[...]] com expressões aritméticas neles são usadas como comando de teste, [...] se comporta incorretamente, enquanto [[...]] corretamente:

    $ if [ 1 > 2 ]; then echo h; else echo b; fi
    h
    $ if [ 1 < 2 ]; then echo h; else echo b; fi
    h
    $ if [[ 1 < 2 ]]; then echo h; else echo b; fi
    h
    $ if [[ 1 > 2 ]]; then echo h; else echo b; fi
    b
    
por Tim 18.03.2016 / 05:51

2 respostas

3

É muito simples. Você só precisa entender [] , [[]] e (()) como animais completamente diferentes.

[ expression ] é apenas uma invocação de um programa [ (apenas um nome diferente para test ) e usa a expressão como argumentos, assim como para todas as chamadas de comandos no bash. Isso significa que você deve usar espaços em branco entre os argumentos, especialmente depois de [ e antes de ] , e palavras-chave e caracteres especiais precisam ser escapados ou citados, e as variáveis são expandidas da maneira usual.

Dentro da expressão, -gt, -lt e relacionados são usados para comparação numérica, enquanto >, < e a classificação são para comparações de cadeias. Pense em [ como nada a ver com bash, apenas chamando um comando que avalia expressões e retorna 0 (verdadeiro) ou diferente de zero (falso), como todos os programas fazem.

Operadores booleanos && e || não podem ser usados lá, porque são interpretados pelo bash e não passados para test como argumentos. -a e -o são usados no lugar. Mas você sempre pode fazer [ test1 ] && [ test2 ] || [ test3 ] , que são 3 invocações de teste, combinadas pelos operadores booleanos comuns de bash (ou seja, se falhar primeiro, o segundo é ignorado).

Observe que bash ainda vem com sua própria implementação de [ (builtin), mas isso não muda a maneira como é tratado sintaticamente.

[[ ]] e (( )) não são substitutos internos para comandos, mas partes de uma sintaxe especial, portanto, regras diferentes se aplicam. Veja man page para detalhes sobre como os nomes das variáveis são curingas são tratados lá. Operadores booleanos && e || têm o significado usual.

O [[ ]] one é centrado em string: todos os comparsions são para strings (mas são mais "modernos", com reconhecimento de localidade do que em [ , embora test possa ser dependente da plataforma). Ele também lida com testes de arquivos, regex e assim por diante.

O (( )) é para expressões aritméticas. Nomes de variáveis não requerem $ , e você pode simplesmente escrever expressões matemáticas lá - isso, claro, inclui comparações (que são numéricas). Comparações neste caso não são diferentes de qualquer outra expressão aritmética, true é 1, false é 0 e você pode escrever coisas como (( x=y*(z>4) )) . Se usado em uma expressão condicional, o valor diferente de zero é verdadeiro e zero é falso. Você também pode capturar o resultado como $(( )) .

Então:

  • [[ ]] condicionais de string, correspondência de padrões e testes de arquivo
  • (( )) expressões aritméticas e condicionais
  • [ ] test comando : lida com ambas as sintaxes especiais não padrão para operadores booleanos e operadores de comparação
por 18.03.2016 / 07:53
0

Uma "expressão condicional" é usada dentro do comando test [ ou [[ .

Então, as suas perguntas 1 e 2 significam o mesmo:

  1. eles podem ser usados em expressões condicionais ?: Sim.
  2. eles podem ser usados em comandos de teste ?: Sim.

No entanto, eles não significam o que você pensa:

$ if [[ 1 < 2 ]]; then echo yes; else echo no; fi
yes
$ if [[ 10 < 2 ]]; then echo yes; else echo no; fi
yes
$ if [[ e < è ]]; then echo yes; else echo no; fi
yes

Essa comparação, como diz o manual:

True if string1 sorts before string2 lexicographically.

Ou seja: na ordem do dicionário (e afetada pela variável LC_COLLATE)

O teste com um simples [ redirecionará a saída para os arquivos:

$ if [ e < è ]; then echo h; else echo b; fi
bash: è: No such file or directory
b

Para que funcione, você precisa usar uma barra invertida (cite as tags < e >):

$ if [ e \< è ]; then echo h; else echo b; fi
h

Mas eu não recomendo usar o < em test .

No outro local em que & lt ;, < =, & gt ;, > = podem ser usados dentro de testes aritméticos, que podem fazer parte de um teste if:

$ if (( 12 <= 15 )); then echo "yes"; fi
yes

Qual, sim, é equivalente a:

$ if [[ 12 -le 15 ]]; then echo "yes"; fi
yes

E bem parecido com:

$ if [ 12 -le 15 ]; then echo "yes"; fi
yes

Então, sim, tudo isso:

<= >= < >     comparison
== !=         equality and inequality 
&&            logical AND
||            logical OR

São usados para expressões condicionais dentro de expressões aritméticas:

$ if (( ( ((2<3)&&(3>7)) * 18 ) == 0 )); then echo "yes"; fi
yes

Que não são as mesmas expressões condicionais do comando test .

    
por 18.03.2016 / 06:43

Tags