Bash: double égal vs -eq

47

Je suis en train de comparer des nombres entiers dans bash (en essayant de voir si l’utilisateur tourne en tant que root), et j’ai trouvé deux façons différentes de le faire:

Double égal:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Je comprends qu'il n'y a pas> = ou <= dans bash, seulement -ge et -le, alors pourquoi y en a ==-t-il s'il y en a -eq?

Y a-t-il une différence dans la façon de comparer les deux côtés?

beatgammit
la source
3
Notez que les espaces entre crochets sont obligatoires: [ $UID -eq 0 ]pas [ $UID -eq 0].
Gilles 'SO- arrête d'être méchant'

Réponses:

51

==est un bashalias spécifique pour =, qui effectue une comparaison sous forme de chaîne (lexicale) au lieu d'une -eqcomparaison numérique. (C'est à l'envers de Perl: les opérateurs de style de mots sont numériques, les opérateurs symboliques lexicaux.)

geekosaur
la source
Cela signifie-t-il que si les deux côtés sont des entiers, les deux côtés sont convertis en chaînes puis comparés?
beatgammit
5
Plus précisément, c'est l'inverse: tout est une chaîne, il est -eqdit bashd'interpréter les chaînes comme des entiers (produire 0sans avertissement si une chaîne n'est pas numérique).
geekosaur
11
@tjameson Pour donner un exemple: [ 01 -eq 1 ]but [ 01 != 1 ].
Gilles 'SO- arrête d'être méchant'
3
Notez que, bien ==qu’en tant [qu’opérateur, il est non standard et ne doit pas être utilisé, il n’est pas spécifique à bash . Il a été introduit par ksh et est également pris en charge par zsh (bien que le premier =doive être cité), yash et l’ [utilitaire GNU (et tout utilitaire de ce type implémenté sous forme de script ksh sur certains systèmes) au moins).
Stéphane Chazelas
@geekosaur Je reçois un avertissement de bash v4.3.42 si ma chaîne n'est pas numérique: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: bonjour: expression entière attendue
Andrew Bainbridge
13

Pour élaborer sur la réponse de Bollovan ...

Il n'y a pas d' opérateur >=ou d' <=opérateur de comparaison pour les chaînes. Mais vous pouvez les utiliser avec la ((...))commande arithmétique pour comparer des nombres entiers.

Vous pouvez également utiliser les autres opérateurs de comparaison de chaînes ( ==, !=, <, >, mais pas =) pour comparer les nombres entiers si vous les utiliser à l' intérieur ((...)).

Exemples

  • Les deux [[ 01 -eq 1 ]]et (( 01 == 1 ))faire des comparaisons entier. Les deux sont vrais.
  • Les deux [[ 01 == 1 ]]et [ 01 = 1 ]faire des comparaisons de chaînes. Les deux sont faux.
  • Les deux (( 01 -eq 1 ))et (( 01 = 1 ))retournera une erreur.

Remarque: La syntaxe double parenthèse [[...]]et la syntaxe double parenthèse ((...))ne sont pas prises en charge par tous les shells.

toxalot
la source
1
Notez que (sauf pour mksh/ zsh(sauf en mode POSIX (bien que ce ne soit pas une fonctionnalité POSIX))), (( 010 == 10 ))renvoie false, car 010serait traité comme un nombre octal (8 en décimal).
Stéphane Chazelas
Notez que si la plupart test/ [mises en œuvre n'ont pas >=/ <=opérateurs ( yash« s [a cependant), expra ces opérateurs, mais il fera la comparaison arithmétique si les arguments sont reconnus comme des nombres ( expr 01 '>=' 1rendements réels, expr X01 '>=' X1fausses déclarations).
Stéphane Chazelas
7

Si vous voulez faire une comparaison d'entiers, vous ferez mieux d'utiliser (()), où vous pouvez aussi utiliser> = etc.

Exemple:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
Bollovan
la source
Ou (( UID == 0 ))ou (( ! UID ))pour que ça compte. Notez que ce ((...))n'est pas standard (une kshfonctionnalité également supportée par bashet zshavec des variations).
Stéphane Chazelas