Dans Bash, deux entiers peuvent être comparés à l'aide d'une expression conditionnelle
arg1 OP arg2
OP est l' un
-eq
,-ne
,-lt
,-le
,-gt
ou-ge
. Ces opérateurs binaires arithmétiques renvoient true si arg1 est respectivement égal, différent de, inférieur, inférieur ou égal, supérieur ou supérieur ou égal à arg2 . Arg1 et arg2 peuvent être des entiers positifs ou négatifs.
ou expression arithmétique:
<= >= < >
Comparaison
== !=
égalité et inégalité
Pourquoi avons-nous deux façons différentes de comparer deux entiers? Quand utiliser quoi?
Par exemple, [[ 3 -lt 2 ]]
utilise une expression conditionnelle et une (( 3 < 2 ))
expression arithmétique. Les deux renvoient 0 lorsque la comparaison est vraie
Lors de la comparaison de deux nombres entiers, ces deux méthodes peuvent-elles toujours être utilisées de manière interchangeable? Si oui, pourquoi Bash a-t-il deux méthodes plutôt qu'une?
= != < <= > >=
comparer les chaînes .1 -eq 01
mais1 != 01
et8 -lt 42
mais8 > 42
Réponses:
Oui, nous avons deux façons différentes de comparer deux entiers.
Il semble que ces faits ne soient pas largement acceptés dans ce forum:
A l' intérieur du langage
[ ]
les opérateurs de comparaison arithmétique sont-eq
,-ne
,-lt
,-le
,-gt
et-ge
.Comme ils sont également à l'intérieur d'une commande de test et à l'intérieur d'un
[[ ]]
.Oui dans ce idiomes,
=
,<
, etc. sont des opérateurs de chaîne.A l' intérieur du langage
(( ))
les opérateurs de comparaison arithmétique sont==
,!=
,<
,<=
,>
et>=
.Non, ce n'est pas une "expansion arithmétique" (qui commence par a
$
) comme$(( ))
. Il est défini comme une "commande composée" dans man bash.Oui, il suit les mêmes règles (internes) de "l'expansion arithmétique" mais n'a pas de sortie, seulement une valeur de sortie. Il pourrait être utilisé comme ceci:
Pourquoi avons-nous deux façons différentes de comparer deux entiers?
Je suppose que ce dernier a
(( ))
été développé comme un moyen plus simple d'effectuer des tests arithmétiques. C'est presque le même que le$(( ))
mais n'a juste aucune sortie.Pourquoi deux? Eh bien la même chose que la raison pour laquelle nous avons deux
printf
(externes et builtin) ou quatre essais (externetest
, builtintest
,[
et[[
). C'est ainsi que les coquilles se développent, améliorant une zone en un an, en améliorant une autre l'année suivante.Quand utiliser quoi?
C'est une question très difficile car il ne devrait pas y avoir de différence effective. Bien sûr, il y a quelques différences dans la façon dont une
[ ]
œuvre et une(( ))
œuvre en interne, mais: laquelle vaut mieux comparer deux entiers? N'importe qui!.Lors de la comparaison de deux nombres entiers, ces deux méthodes peuvent-elles toujours être utilisées de manière interchangeable?
Pour deux chiffres, je suis obligé de dire oui.
Mais pour les variables, les extensions, les opérations mathématiques, il peut y avoir des différences clés qui devraient favoriser l'une ou l'autre. Je ne peux pas dire que les deux sont absolument égaux. D'une part, le
(( ))
pourrait effectuer plusieurs opérations mathématiques en séquence:Si oui, pourquoi Bash a-t-il deux méthodes plutôt qu'une?
Si les deux sont utiles, pourquoi pas?.
la source
=
est une affectation et==
une comparaison dans les extensions arithmétiques. La question le cite correctement. Mais la réponse est fausse.Historiquement, la
test
commande a existé en premier (au moins aussi loin que Unix Seventh Edition en 1979). Il a utilisé les opérateurs=
et!=
pour comparer des chaînes, et-eq
,-ne
,-lt
, etc. , pour comparer les chiffres. Par exemple,test 0 = 00
est faux, maistest 0 -eq 00
vrai. Je ne sais pas pourquoi cette syntaxe a été choisie, mais c'était peut-être pour éviter d'utiliser<
and>
, que le shell aurait analysé en tant qu'opérateurs de redirection. Latest
commande a obtenu une autre syntaxe quelques années plus tard:[ … ]
équivaut àtest …
.La
[[ … ]]
syntaxe conditionnelle, à l'intérieur de laquelle<
et>
peut être utilisée comme opérateur sans guillemet, a été ajoutée plus tard, dans ksh. Il a conservé la compatibilité descendante avec[ … ]
, donc il a utilisé les mêmes opérateurs, mais a ajouté<
et>
pour comparer des chaînes (par exemple,[[ 9 > 10 ]]
mais[[ 9 -lt 10 ]]
). Pour plus d'informations, voir Utilisation d'un support simple ou double - bashLes expressions arithmétiques sont également venues plus tard que la
test
commande, dans le shell Korn , à un moment donné dans les années 1980. Ils ont suivi la syntaxe du langage C, qui était très populaire dans les cercles Unix. Ils ont donc utilisé les opérateurs de C:==
pour l'égalité,<=
pour le plus ou moins, etc.Unix Seventh Edition n'avait pas d'expressions arithmétiques, mais il avait la
expr
commande , qui implémentait également une syntaxe de type C pour les opérations entières, y compris ses opérateurs de comparaison. Dans un script shell, les caractères<
et>
devaient être cités pour les protéger du shell, par exempleif expr 1 \< 2; …
est équivalent àif test 1 -lt 2; …
. L'ajout d'expressions arithmétiques au shell a rendu la plupart des utilisationsexpr
obsolètes, donc ce n'est pas bien connu aujourd'hui.Dans un script sh, vous utiliseriez généralement des expressions arithmétiques pour calculer une valeur entière et
[ … ]
comparer des nombres entiers.Dans un script ksh, bash ou zsh, vous pouvez utiliser les
((…))
deux.Le
[[ … ]]
formulaire est utile si vous souhaitez utiliser des conditions impliquant d'autres choses que des entiers.la source
Selon la page de manuel de test, = et! = Sont utilisés pour les comparaisons de chaînes tandis que les expressions -eq, -gt, -lt, -ge, -le et -ne sont des comparaisons entières. J'ai toujours suivi cette convention lors de l'écriture de scripts shell et cela fonctionne toujours. Sachez que si vous avez des variables dans l'expression, vous devrez peut-être citer les variables d'une manière ou d'une autre pour éviter de faire une comparaison nulle.
Sur papier, nous faisons des comparaisons chaîne / nombre sans trop y penser. Un ordinateur d'autre part ne sait pas si 987 est un nombre ou une chaîne de caractères. Vous avez besoin des différents opérateurs pour dire à l'ordinateur ce qu'il faut faire pour obtenir le bon résultat. Il y a quelques informations supplémentaires ici qui expliquent une partie de l'histoire. Essentiellement, les variables ne sont pas typées et sont restées ainsi pour la compatibilité historique.
la source
=
et!=
sont des opérateurs arithmétiques, alors que la page de manueltest
montre seulement des opérateurs d'expression conditionnelle.