137 votes

Comparer des entiers en bash, opérateur unaire attendu

Le code suivant donne

[ : -ge : opérateur unaire attendu

quand

i=0

if [ $i -ge 2 ]
then
    #some code
fi

Pourquoi ?

295voto

vladr Points 34562

Votre problème vient du fait que $i a une valeur vide lorsque votre déclaration échoue. Toujours citer vos variables lors des comparaisons s'il y a la moindre chance que l'une d'entre elles soit vide, par exemple :

if [ "$i" -ge 2 ] ; then
  ...
fi

Cela est dû à la façon dont le shell traite les variables. Reprenons l'exemple original,

if [ $i -ge 2 ] ; then ...

La première chose que fait l'interpréteur de commandes en exécutant cette ligne de code particulière est de substituer la valeur de la variable $i tout comme votre éditeur préféré chercher et remplacer la fonction serait. Supposons donc que $i est vide ou, encore plus illustratif, supposez que $i est un tas d'espaces ! Le shell remplacera $i comme suit :

if [     -ge 2 ] ; then ...

Maintenant que les substitutions de variables sont effectuées, l'interpréteur de commandes procède à la comparaison et.... échoue parce qu'il ne peut rien voir d'intelligible pour l'utilisateur. gauche de -gt . Cependant, en citant $i :

if [ "$i" -ge 2 ] ; then ...

devient :

if [ "    " -ge 2 ] ; then ...

L'interpréteur de commandes voit maintenant les guillemets et sait qu'il s'agit en fait de comparer quatre blancs à 2. if .

Vous avez également la possibilité de spécifier une valeur par défaut pour le paramètre $i si $i est vide, comme suit :

if [ "${i:-0}" -ge 2 ] ; then ...

Cela remplacera la valeur 0 par la valeur $i est $i est indéfinie. Je maintiens toujours les guillemets car, encore une fois, si $i est un tas de blancs, il ne compte pas comme indéfini il ne sera pas remplacé par 0, et vous rencontrerez à nouveau le problème.

Veuillez lire ce quand vous aurez le temps. L'interpréteur de commandes est considéré comme une boîte noire par beaucoup, mais il fonctionne avec très peu de règles très simples - une fois que vous êtes conscient de ces règles (l'une d'entre elles étant le fonctionnement des variables dans l'interpréteur de commandes, comme expliqué ci-dessus), l'interpréteur de commandes n'aura plus de secrets pour vous.

7 votes

La variable de citation donnera lieu à une nouvelle erreur du type expression entière attendue

0 votes

@Néstor mauvais la citation d'une variable ne déclenchera PAS une nouvelle erreur du genre expression entière attendue si la variable est numérique ; fournir une valeur de variable non numérique, qu'elle soit citée ou non, sera entraîner ladite erreur.

45voto

PEZ Points 9662

Il ne me donne pas cette erreur. Néanmoins, si vous utilisez bash, il est préférable d'utiliser la fonction intégrée [[ que la commande test ([).

if [[ $i -ge 2 ]]

6voto

starblue Points 29696

D'après le message d'erreur, la valeur de i était la chaîne vide lorsque vous l'avez exécuté, et non 0.

6voto

Roman Newaza Points 3945

Je dois ajouter mes 5 centimes. Je vois que tout le monde utilise [ ou [[ mais il convient de préciser qu'ils ne font pas partie de la syntaxe if.

Pour les comparaisons arithmétiques, utilisez ((...)) à la place.

((...)) est une commande arithmétique, qui renvoie un état de sortie de 0 si l'expression est non nulle, ou 1 si l'expression est nulle. Également utilisé comme synonyme de "let", si des effets secondaires (affectations) sont nécessaires.

Voir : Expression arithmétique

2voto

Fernando Miguélez Points 7532

Votre morceau de script fonctionne très bien. Etes-vous sûr que vous n'assignez rien d'autre avant le if à "i" ?

Une erreur courante consiste également à ne pas laisser d'espace après et avant les crochets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X