C'est l'inverse: =
et ==
sont pour les comparaisons de chaînes, -eq
est pour les comparaisons numériques. -eq
est dans la même famille que -lt
, -le
, -gt
, -ge
et -ne
, si cela vous aide même qui est qui.
==
est un bash-isme, au fait. Il vaut mieux utiliser le POSIX =
. En bash, les deux sont équivalents, et en clair, sh =
est le seul qui fonctionne.
$ a=foo
$ [ "$a" = foo ]; echo "$?" # POSIX sh
0
$ [ "$a" == foo ]; echo "$?" # bash specific
0
$ [ "$a" -eq foo ]; echo "$?" # wrong
-bash: [: foo: integer expression expected
2
(Note latérale: citez ces extensions de variables! Ne laissez pas les doubles guillemets ci-dessus.)
Si vous écrivez un #!/bin/bash
script, je vous recommande d' utiliser à la [[
place . La forme doublée a plus de fonctionnalités, une syntaxe plus naturelle et moins de pièges qui vous feront trébucher. Les guillemets doubles ne sont plus nécessaires autour $a
, pour un:
$ [[ $a == foo ]]; echo "$?" # bash specific
0
Voir également:
[[
dans son ensemble, est un ksh-ism des années 1980 que bash (et de nombreux autres shells) a adopté. C'est toute la question - si vous avez[[
du tout , alors vous pouvez supposer que toutes les extensions KSH mises en œuvre autour d' elle (fnmatch()
correspondance de motif de style, ERE expressions régulières avec=~
, et oui, la suppression de la chaîne de division et système de fichiers globbing) seront disponible. Comme[[
la syntaxe n'est pas POSIX dans son intégralité, il n'y a pas de perte de portabilité supplémentaire en supposant que les fonctionnalités avec lesquelles elle est née seront disponibles.[[ $var = $pattern ]]
, si vous voulez que ce qui serait autrement interprété comme un modèle fnmatch soit plutôt interprété comme une chaîne littérale. La chaînefoo
n'a pas d'interprétation non littérale, ce qui rend les guillemets totalement sûrs; c'est seulement si l'OP voulait correspondre, disons,foo*
(avec l'astérisque comme littéral, ne signifiant rien qui puisse venir après la chaînefoo
) que des guillemets ou des échappements seraient nécessaires.[[
étaient un bashisme (indiquant que c'était la seule raison pour laquelle vous ne donniez pas la réponse un +1).[ ... ]
et double signe égal==
. : - /Cela dépend de la construction de test autour de l'opérateur. Vos options sont les doubles parenthèses, les doubles accolades, les accolades simples ou le test
Si vous utilisez ((...)) , vous testez l'équité arithmétique avec
==
comme en C:(Remarque:
0
signifietrue
au sens Unix et non nul est un test échoué)L'utilisation
-eq
de la double parenthèse est une erreur de syntaxe.Si vous utilisez [...] (ou une accolade simple) ou [[...]] (ou une double accolade), ou
test
vous pouvez utiliser l'une des options -eq, -ne, -lt, -le, -gt ou -ge comme comparaison arithmétique .L'
==
intérieur des accolades simples ou doubles (outest
commande) est l'un des opérateurs de comparaison de chaînes :En tant qu'opérateur de chaîne,
=
équivaut à==
et notez l'espace blanc autour=
ou==
son obligatoire.Bien que vous puissiez le faire
[[ 1 == 1 ]]
ou[[ $(( 1+1 )) == 2 ]]
il teste l'égalité des chaînes - pas l'égalité arithmétique.Donc
-eq
produit le résultat probablement attendu que la valeur entière de1+1
est égale à2
même si le RH est une chaîne et a un espace de fin:Alors qu'une comparaison de chaînes de la même sélection prend l'espace de fin et donc la comparaison de chaînes échoue:
Et une comparaison de chaînes erronée peut produire la mauvaise réponse complète. «10» est inférieur lexicographiquement à «2», donc une comparaison de chaînes renvoie
true
ou0
. Tant de gens sont mordus par ce bug:vs le test correct pour 10 étant arithmétiquement inférieur à 2:
Dans les commentaires, il y a une question de la raison technique en utilisant l'entier
-eq
sur les chaînes renvoie True pour les chaînes qui ne sont pas les mêmes:La raison en est que Bash n'est pas typé . Le
-eq
fait que les chaînes soient interprétées comme des entiers si possible, y compris la conversion de base:Et
0
si Bash pense que ce n'est qu'une chaîne:Donc
[[ "yes" -eq "no" ]]
équivaut à[[ 0 -eq 0 ]]
Dernière note: de nombreuses extensions spécifiques à Bash des constructions de test ne sont pas POSIX et échoueront donc dans d'autres shells. D'autres coques ne supportent généralement pas
[[...]]
et((...))
ou==
.la source
[[ "yes" -eq "no" ]]
retour de True. Comment bash contraint-il ces chaînes à des valeurs entières pouvant être comparées? ;-)[[ "yes" -eq "no" ]]
équivaut à[[ "yes" -eq 0 ]]
ou[[ "yes" -eq "any_noninteger_string" ]]
- All True. La-eq
comparaison d'entiers force. Le"yes"
est interprété comme un entier0
; la comparaison est True si l'autre entier est l'un0
ou l' autre ou si le résultat de la chaîne l'est0
.==
dans les échantillons de code et ne mentionnant que (portable, standardisé) en=
dessous.==
est un alias spécifique à bash pour=
et il effectue une comparaison de chaîne (lexicale) au lieu d'une comparaison numérique.eq
étant une comparaison numérique bien sûr.Enfin, je préfère généralement utiliser le formulaire
if [ "$a" == "$b" ]
la source
==
ici est une mauvaise forme, comme seul le=
spécifie POSIX.==
mettez-le entre[[
et]]
. (Et assurez-vous que la première ligne de votre script spécifie à utiliser/bin/bash
.)Guys: Plusieurs réponses montrent des exemples dangereux. L'exemple d'OP
[ $a == $b ]
utilisait spécifiquement la substitution de variables sans guillemets (à partir de l'édition d'octobre 2017). Car[...]
c'est sûr pour l'égalité des chaînes.Mais si vous allez énumérer des alternatives comme
[[...]]
, vous devez également informer que le côté droit doit être cité. S'il n'est pas cité, c'est une correspondance de modèle! (De la page de manuel de bash: "N'importe quelle partie du modèle peut être citée pour forcer sa correspondance sous forme de chaîne.").Ici, dans bash, les deux instructions donnant "yes" sont des correspondances de modèle, les trois autres sont l'égalité des chaînes:
la source
[ "$lht" = "$rht" ]
avec les guillemets pour être fiable même pour l'égalité. Si vous avez créé un fichier avectouch 'Afoo -o AB'
,[ $lft = $rht ]
retournera true, même si ce nom de fichier n'est pas du tout identique àAB
.