web-dev-qa-db-fra.com

Comparer entier 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?

134
Filip Ekberg

Votre problème provient du fait que $i a une valeur vide lorsque votre instruction échoue. Citez toujours vos variables lors de comparaisons s’il existe la moindre chance que l’une d’elles soit vide, par exemple:

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

Cela est dû à la manière dont le shell traite les variables. Supposons l'exemple d'origine,

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

La première chose que le shell fait en exécutant cette ligne de code particulière est de remplacer la valeur de $i, tout comme le ferait la fonction search & replace de votre éditeur favori. Supposons donc que $i soit vide ou, encore plus illustratif, que $i soit un tas d’espaces! Le shell remplacera $i comme suit:

if [     -ge 2 ] ; then ...

Maintenant que les substitutions de variables sont effectuées, le shell procède à la comparaison et .... échoue car il ne voit rien d'intelligible pour le left ​​de -gt. Cependant, citant $i:

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

devient:

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

Le shell voit maintenant les guillemets, et sait que vous comparez en réalité quatre blancs à 2 et ignorera le if.

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

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

Ceci remplacera la valeur 0 au lieu de $i est $i est indéfini. Je maintiens toujours les guillemets parce que, encore une fois, si $i est un groupe de blancs, il ne compte pas comme ndefined, il ne sera pas remplacé par 0 et vous rencontrerez le problème. encore une fois.

S'il vous plaît lire this lorsque vous avez le temps. Le Shell est traité par beaucoup comme une boîte noire, mais il fonctionne avec très peu de règles très simples - une fois que vous savez quelles sont ces règles (l'une d'entre elles est le fonctionnement des variables dans le Shell, comme expliqué ci-dessus), le Shell va n'a plus de secrets pour toi.

289
vladr

A en juger par le message d'erreur, la valeur de i était la chaîne vide lorsque vous l'avez exécutée, pas 0.

6
starblue

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

Pour les comparaisons arithmétiques, utilisez plutôt ((...)).

((...)) est une commande arithmétique qui renvoie un état de sortie égal à 0 si l'expression est différente de zéro ou à 1 si elle est égale à zéro. Également utilisé comme synonyme de "let", si des effets secondaires (affectations) sont nécessaires.

Voir: ArithmeticExpression

6
Roman Newaza

Votre script fonctionne parfaitement. Êtes-vous sûr de ne rien assigner d’autre avant le if à "i"?

Une erreur courante consiste également à ne pas laisser d'espace entre les crochets.

2
Fernando Miguélez