Bash: o dobro é igual a -eq

47

Estou fazendo uma comparação de números inteiros no bash (tentando ver se o usuário está executando como root) e encontrei duas maneiras diferentes de fazer isso:

O dobro é igual a:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Eu entendo que não há> = ou <= no bash, apenas -ge e -le, então por que existe um ==se houver um -eq?

Existe alguma diferença na maneira como compara os dois lados?

beatgammit
fonte
3
Observe que os espaços entre colchetes são necessários:, [ $UID -eq 0 ]não [ $UID -eq 0].
Gilles 'SO- stop be evil'

Respostas:

50

==é um bashalias específico para =, que executa uma comparação de sequência (lexical) em vez da -eqcomparação numérica. (É o contrário do Perl: os operadores de estilo de palavra são numéricos, os simbólicos, lexicais.)

geekosaur
fonte
Isso significa que, se os dois lados são números inteiros, ele converte os dois lados em seqüências de caracteres e os compara?
beatgammit
5
Mais precisamente, é o contrário: tudo é uma string, -eqindica bashpara interpretar as strings como números inteiros (produzindo 0sem aviso se a string não for numérica).
Geekosaur
11
@tjameson Para dar um exemplo: [ 01 -eq 1 ]mas [ 01 != 1 ].
Gilles 'SO- stop be evil'
3
Note-se que, enquanto ==como um [operador não é padrão e não deve ser usado, ele não é específico da festa . Foi introduzido pelo ksh e também é suportado pelo zsh (embora o primeiro =precise ser citado), pelo yash e pelo [utilitário GNU (e quaisquer utilitários implementados como scripts ksh em alguns sistemas) pelo menos).
Stéphane Chazelas
@geekosaur Eu começo um aviso de v4.3.42 festa se minha cadeia não é numérico: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: Olá: expressão inteira esperado
Andrew Bainbridge
13

Para elaborar a resposta de bollovan ...

Não há operador de comparação >=ou <=para seqüências de caracteres. Mas você pode usá-los com o ((...))comando aritmético para comparar números inteiros.

Você também pode usar os outros operadores de comparação string ( ==, !=, <, >, mas não =) para comparar inteiros se você usá-los para dentro ((...)).

Exemplos

  • Ambas [[ 01 -eq 1 ]]e (( 01 == 1 ))fazem comparações inteiras. Ambos são verdadeiros.
  • Ambos [[ 01 == 1 ]]e [ 01 = 1 ]fazem comparações de strings. Ambos são falsos.
  • Ambos (( 01 -eq 1 ))e (( 01 = 1 ))retornará um erro.

Nota: A sintaxe de colchete duplo [[...]]e a sintaxe de parênteses duplos ((...))não são suportadas por todos os shells.

toxalote
fonte
1
Observe que (exceto para mksh/ zsh(exceto no modo POSIX (embora esse não seja um recurso POSIX))), (( 010 == 10 ))retornaria false porque 010seria tratado como um número octal (8 em decimal).
Stéphane Chazelas
Note-se que enquanto a maioria test/ [implementações não tem >=/ <=operadores ( yash's [tem embora), exprtem tais operadores, que ele vai fazer a comparação aritmética se os argumentos são reconhecidos como números ( expr 01 '>=' 1retornar true, expr X01 '>=' X1retorna falso).
Stéphane Chazelas
7

Se você quiser fazer uma comparação inteira, usará melhor (()), onde também poderá usar> = etc.

Exemplo:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
bollovan
fonte
Ou (( UID == 0 ))ou (( ! UID ))para esse assunto. Observe que isso ((...))não é padrão (um kshrecurso também suportado por bashe zshcom variações).
Stéphane Chazelas