Vergleichen Sie die Ganzzahl in Bash, ein unärer Operator wird erwartet

137

Der folgende Code gibt

[: -ge: unärer Operator erwartet

wann

i=0

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

Warum?

Filip Ekberg
quelle

Antworten:

295

Ihr Problem ergibt sich aus der Tatsache, dass $iein leerer Wert vorliegt, wenn Ihre Anweisung fehlschlägt. Zitieren Sie Ihre Variablen immer, wenn Sie Vergleiche durchführen, wenn die geringste Wahrscheinlichkeit besteht, dass eine davon leer ist, z.

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

Dies liegt daran, wie die Shell Variablen behandelt. Nehmen Sie das ursprüngliche Beispiel an,

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

Das erste, was die Shell beim Ausführen dieser bestimmten Codezeile tut, ist das Ersetzen des Werts von $i, genau wie es die Such- und Ersetzungsfunktion Ihres bevorzugten Editors tun würde. Nehmen wir also an, dass dies $ileer ist oder, noch anschaulicher, dass $ies sich um eine Reihe von Leerzeichen handelt! Die Shell wird $iwie folgt ersetzt:

if [     -ge 2 ] ; then ...

Nachdem die Variablensubstitutionen durchgeführt wurden, fährt die Shell mit dem Vergleich fort und .... schlägt fehl, weil links von ihr nichts Verständliches zu sehen ist -gt. Zitiert jedoch $i:

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

wird:

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

Die Shell sieht jetzt die doppelten Anführungszeichen und weiß, dass Sie tatsächlich vier Leerzeichen mit zwei vergleichen, und überspringt das if.

Sie haben auch die Möglichkeit, einen Standardwert für $iif $iwie leer anzugeben :

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

Dies ersetzt den Wert 0 anstelle von $iis $iist undefiniert. Ich behalte die Anführungszeichen weiterhin bei, da wiederum, wenn $ies sich um eine Reihe von Leerzeichen handelt, diese nicht als undefiniert gelten , nicht durch 0 ersetzt werden und Sie erneut auf das Problem stoßen.

Bitte lesen Sie dies, wenn Sie Zeit haben. Die Shell wird von vielen wie eine Black Box behandelt, arbeitet jedoch mit sehr wenigen und sehr einfachen Regeln - sobald Sie wissen, was diese Regeln sind (eine davon ist, wie Variablen in der Shell funktionieren, wie oben erläutert), wird die Shell dies tun habe keine Geheimnisse mehr für dich.

vladr
quelle
7
Das Zitieren einer Variablen führt zu einem neuen Fehler, wie er erwartet wird
Néstor,
@ Néstor falsch , das Zitieren einer Variablen führt NICHT zu einem neuen Fehler wie dem erwarteten Ganzzahlausdruck, wenn die Variable numerisch ist. Das Bereitstellen eines nicht numerischen Variablenwerts, ob in Anführungszeichen oder nicht, führt zu diesem Fehler.
Vladr
6

Nach der Fehlermeldung zu urteilen, war der Wert von i die leere Zeichenfolge, als Sie sie ausgeführt haben, nicht 0.

Sternenblau
quelle
6

Ich muss meine 5 Cent hinzufügen. Ich sehe, dass jeder [oder verwendet [[, aber es ist erwähnenswert, dass sie nicht Teil der if-Syntax sind.

Verwenden Sie ((...))stattdessen für arithmetische Vergleiche .

((...)) ist ein arithmetischer Befehl, der einen Exit-Status von 0 zurückgibt, wenn der Ausdruck ungleich Null ist, oder 1, wenn der Ausdruck Null ist. Wird auch als Synonym für "let" verwendet, wenn Nebenwirkungen (Zuweisungen) erforderlich sind.

Siehe: ArithmeticExpression

Roman Newaza
quelle
2

Ihr Skript funktioniert einfach großartig. Sind Sie sicher, dass Sie "i" vor dem if nichts anderes zuweisen?

Ein häufiger Fehler ist auch, nach und vor den eckigen Klammern kein Leerzeichen zu lassen.

Fernando Miguélez
quelle