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:
$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1
(Remarque: 0
signifie true
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 .
$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0
L' ==
intérieur des accolades simples ou doubles (ou test
commande) est l'un des opérateurs de comparaison de chaînes :
$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1
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 de 1+1
est égale à2
même si le RH est une chaîne et a un espace de fin:
$ [[ $(( 1+1 )) -eq "2 " ]]; echo $?
0
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:
$ [[ $(( 1+1 )) == "2 " ]]; echo $?
1
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
ou 0
. Tant de gens sont mordus par ce bug:
$ [[ 10 < 2 ]]; echo $?
0
vs le test correct pour 10 étant arithmétiquement inférieur à 2:
$ [[ 10 -lt 2 ]]; echo $?
1
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:
$ [[ "yes" -eq "no" ]]; echo $?
0
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:
$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0
Et 0
si Bash pense que ce n'est qu'une chaîne:
$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1
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==
.
[[
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.