quais são as diferenças entre '==' e '=' em expressões condicionais?

0

Do manual do bash, para expressões condicionais

string1 == string2
string1 = string2

True if the strings are equal.

  1. When used with the [[ command, this performs pattern matching as described above (see Section 3.2.4.2 [Conditional Constructs], page 10).

    • O que significa "correspondência de padrões" aqui?

    • O que é "correspondência de padrões" em oposição a aqui?

    • Se não for usado com [[ , mas com outros comandos, o que "isso" executa?

  2. ‘=’ should be used with the test command for posix conformance.

    • O que o POSIX diz aqui?

    • Qual é a frase a que se opõe?

    • Pode == ser usado com o comando test ? Eu tentei e parece que sim.

    • Pode = ser usado com outros comandos além de test ? Eu tentei = com [[ e [ e parece que sim.

  3. quais são as diferenças entre == e = ?

    No Bash 4.3, eu tentei == e = com test , [[ e [ . %código% e == parecem iguais para mim.

    As expressões = e == podem ser usadas de maneira intercambiável em qualquer expressão condicional?

Obrigado.

    
por Tim 26.07.2017 / 21:58

2 respostas

8

test (ou [ ... ] ) só sabe quem tem um único sinal de igual:

s1 = s2
True if the strings s1 and s2 are identical; otherwise, false.

Mas Bash aceita o duplo sinal de igual também, embora a ajuda embutida não admita isso (o manual ):

$ help test | grep =  -A1
  STRING1 = STRING2
                 True if the strings are equal.
  STRING1 != STRING2
                 True if the strings are not equal.

Quanto aos outros shells, isso depende:

$ dash -c '[ x == x ] && echo foo'
dash: 1: [: x: unexpected operator
$ zsh -c '[ x == x ] && echo foo'
zsh:1: = not found
$ ksh93 -c '[ x == x ] && echo foo'
foo

zsh é um pouco estranho aqui, == é considerado um operador especial, por isso deve ser citado:

$ zsh -c '[ x "==" x ] && echo foo'
foo

A utilidade externa test / [ do GNU coreutils no meu Debian suporta == (mas o manual não admite isso, o que o OS X não faz.

Portanto, com test / [ .. ] , use = , pois é mais amplamente suportado.

Com o [[ ... ]] construct , ambos = e == são iguais (pelo menos no Bash) e o lado direito do operador é tomado como um padrão, como em um arquivo glob, a menos que seja citado. (Nomes de arquivos não são expandidos dentro de [[ ... ]] )

$ bash -c '[[ xxx == x* ]] && echo foo'
foo

Mas é claro que essa construção não é padrão:

$ dash -c '[[ xxx == x* ]] && echo foo'
dash: 1: [[: not found
    
por 26.07.2017 / 22:40
2

No bash, existem quatro condições sobre igualdade:

  • O simples e mais básico (e somente compatível com posix) = dentro de [ … ] (ou teste):
    Só realiza igualdade (byte por byte) de duas strings.

     STRING1 = STRING2
                 True if the strings are equal.
    
  • O estendido == . Que ainda realiza (apenas) um teste de igualdade.

    $ [ aaaa == aaaa ] && echo yes
    yes
    
    $ [ aaaa == a* ] && echo yes
    $
    

    Tenha cuidado para que o a* sem aspas seja expandido para um nome de arquivo (ou vários) se um nome de arquivo correspondente existir no pwd. Em específico: um arquivo existente chamado aaaa fará o código de saída sim. Se não houver arquivos correspondentes, a comparação exata será afetada pelas opções de shell failglob e nullglob.

  • Um = dentro de um [[ é exatamente equivalente a:

  • Um == dentro de um [[ faz a correspondência byte a byte e glob.

    Se a string ou variável do lado direito do == for citada, será feita uma comparação de bytes. Se todos os bytes forem iguais, o resultado do [[ é "bom" (0).

    Se a string, ou preferível em todos os casos: uma variável, não estiver marcada, a correspondência será executada como em um glob de nome de arquivo.

    $ [[ aaaa == "aaaa" ]] && echo yes
    yes
    
    $ a='aaaa'
    $ [[ aaaa == "$a" ]] && echo yes
    yes
    
    $ a='a*'
    $ [[ aaaa == "$a" ]] && echo yes
    $
    
    $ a='a*'
    $ [[ aaaa == $a ]] && echo yes
    yes
    

É interessante notar que o aaaa sem aspas também funciona:

$ a='aaaa'
$ [[ aaaa = $a ]] && echo yes
yes

Isso acontece porque a string dentro da variável não possui nenhum caractere de glob expansível * , + , ? , [ e estendido (se ativado) | , @ e ! . Mas isso geralmente é uma aposta arriscada para usar.

    
por 27.07.2017 / 07:02

Tags