Par curiosité, lors de la comparaison d'une variable bash (sa valeur étant un integer
), il est possible de la tester par rapport à une valeur prédéfinie déclarée en tant que int
ou en tant que string
.
Exemple de script :
#!/bin/bash
f1()
{
[ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}
f2()
{
[[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}
f1 $1
f2 $1
Sortie :
$ ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int
et
$ ./param.sh blah
$
Les deux fonctions se comportent de la même manière, et je me demande donc s'il existe une méthode préférée lors de la vérification d'une variable entière? J'irais pour la vérification int
contre int
car c'est plus strict mais je me demande s'il y a des inconvénients à le faire string
?
Dans ce cas, f2()
la comparaison est également plus stricte, c'est-à-dire que le passage d'une valeur décimale la cassera, alors que f1()
cela ne posera aucun problème.
Réponses:
Oui, beaucoup de différences. Par exemple,
=
vérifie l'égalité exacte des chaînes, mais-eq
évalue les deux expressions de manière arithmétique avant de vérifier l'égalité:De plus, la chaîne vide se trouve être numériquement égale à zéro:
Et une toute autre classe de différences apparaît lorsque vous intégrez les opérateurs de comparaison - en considérant
<
vs-lt
, par exemple:Cela est dû au fait que la chaîne "2" est alphabétiquement après la chaîne "10" (puisque 1 vient avant 2), mais le nombre "2" est numériquement inférieur au nombre "10".
la source
(( ... ))
des opérations numériques.(( " 1 " == 1 )) && echo yes || echo no
résultatsyes
La comparaison entiers vs chaînes devient plus significative lorsque vous comparez plus ou moins que:
Le premier échoue car 9 vient après 11 lorsqu'il est trié lexicographiquement.
Notez que l'utilisation de guillemets ne détermine pas si vous comparez des chaînes ou des nombres, l'opérateur le fait. Vous pouvez ajouter ou supprimer les citations ci-dessus, cela ne fait aucune différence. Bash capture les variables non définies entre crochets, donc les guillemets ne sont pas nécessaires. L'utilisation de guillemets avec des crochets simples pour les tests numériques ne vous sauvera pas puisque:
est quand même une erreur ("expression entière requise"). Les citations sont une sauvegarde efficace avec des comparaisons de chaînes entre crochets simples:
Remarque dans les doubles crochets,
""
seront ,-eq 0
mais pas== 0
.la source
[[
est suffisamment intelligente pour se rappeler où se trouvent les variables, et elle ne sera pas dupée par des variables vides. Les crochets simples ([
) n'ont pas cette fonctionnalité et nécessitent des guillemets.[[ -lt 11 ]]
est une erreur, maisnothing=; [[ $nothing -lt 11 ]]
ne l'est pas. J'ai retravaillé un peu le dernier paragraphe.En plus de ce qui a été dit.
La comparaison pour l'égalité est plus rapide avec les nombres, bien que dans les scripts shell, il soit rare que vous ayez besoin d'un calcul rapide.
la source
=
, car l'utilisation-eq
correspondrait également à "+123". Si vous vouliez savoir "Est-ce que cette variable, lorsqu'elle est évaluée comme une expression arithmétique, est égale à 123", vous ne pouvez utiliser que-eq
. La seule fois où je peux voir où un programmeur ne se soucie pas de la définition de l'égalité a été utilisée, c'est quand il sait que le contenu de la variable est contraint à un modèle particulier à l'avance.b=234
) correspond à ce modèle - vous savez que ce n'est pas +234 ou "234" ou "233 + 1", puisque vous l'avez attribué vous-même, donc vous savez qu'il le compare en tant que chaîne et en tant que nombre sont également valables. Mais le script de l'OP, puisqu'il prend l'entrée comme argument de ligne de commande, n'a pas cette contrainte - pensez à l'appeler comme./param.sh 0+1
ou./param.sh " 1"