Bash: Doppel gleich vs -eq

47

Ich führe einen Ganzzahlvergleich in Bash durch (versuche herauszufinden, ob der Benutzer als Root ausgeführt wird) und habe zwei verschiedene Möglichkeiten gefunden, dies zu tun:

Doppel gleich:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Ich verstehe, dass es in bash kein> = oder <= gibt, nur -ge und -le. Warum gibt es also ein, ==wenn es ein gibt -eq?

Gibt es einen Unterschied in der Art und Weise, wie beide Seiten verglichen werden?

Beatgammit
quelle
3
Beachten Sie, dass in eckigen Klammern Leerzeichen erforderlich sind:, [ $UID -eq 0 ]nicht [ $UID -eq 0].
Gilles 'SO- hör auf böse zu sein'

Antworten:

50

==ist ein bash-spezifischer Alias ​​für =, der anstelle des -eqnumerischen Vergleichs einen String-Vergleich (lexikalisch) durchführt . (Es ist rückwärts von Perl: Die Operatoren im Wortstil sind numerisch, die symbolischen lexikalisch.)

Geekosaurier
quelle
Bedeutet das, dass, wenn beide Seiten Ganzzahlen sind, beide Seiten in Zeichenfolgen konvertiert und dann verglichen werden?
Beatgammit
5
Genauer gesagt ist es umgekehrt: alles , was ein String ist, -eqsagt bashdie Saiten als ganze Zahlen zu interpretieren (Herstellung 0ohne eine Warnung , wenn ein String nicht numerisch ist).
Geekosaurier
11
@tjameson Um ein Beispiel zu nennen: [ 01 -eq 1 ]aber [ 01 != 1 ].
Gilles 'SO- hör auf böse zu sein'
3
Beachten Sie, dass ==ein [Operator zwar nicht dem Standard entspricht und nicht verwendet werden sollte, jedoch nicht bash-spezifisch ist . Es wurde von ksh eingeführt und wird auch von zsh (obwohl das erste =in Anführungszeichen gesetzt werden muss), yash und dem GNU- [Dienstprogramm (und allen solchen Dienstprogrammen, die auf einigen Systemen als ksh-Skripte implementiert sind) unterstützt.
Stéphane Chazelas
@geekosaur Ich erhalte eine Warnung von Bash v4.3.42, wenn mein String nicht numerisch ist: $ if [ "hello" -eq 0 ]; then echo true; fi Bash: [: Hallo: Integer-Ausdruck erwartet
Andrew Bainbridge
13

Um die Antwort von Bollovan zu erläutern ...

Es gibt keinen >=oder <=Vergleichsoperator für Zeichenfolgen. Sie können sie jedoch mit dem ((...))arithmetischen Befehl verwenden, um Ganzzahlen zu vergleichen.

Sie können auch die anderen String - Vergleichsoperator ( ==, !=, <, >, aber nicht =) ganze Zahlen zu vergleichen , wenn man sie nach innen verwenden ((...)).

Beispiele

  • Beide [[ 01 -eq 1 ]]und (( 01 == 1 ))führen Ganzzahlvergleiche durch. Beides ist wahr.
  • Beide [[ 01 == 1 ]]und [ 01 = 1 ]führen Zeichenfolgenvergleiche durch. Beides ist falsch.
  • Beide (( 01 -eq 1 ))und (( 01 = 1 ))geben einen Fehler zurück.

Hinweis: Die Syntax in [[...]]doppelten Klammern und die Syntax ((...))in doppelten Klammern werden nicht von allen Shells unterstützt.

Toxalot
quelle
1
Beachten Sie, dass (mit Ausnahme von mksh/ zsh(mit Ausnahme des POSIX-Modus (obwohl dies keine POSIX-Funktion ist)) (( 010 == 10 ))false zurückgegeben wird, da 010dies als Oktalzahl behandelt wird (8 in Dezimalform).
Stéphane Chazelas
Beachten Sie, dass während die meisten test/ [Implementierungen nicht haben >=/ <=Operatoren ( yash‚s [hat zwar), exprhat eine solche Operatoren, obwohl es arithmetische Vergleich tun wird , wenn die Argumente als Zahlen (anerkannt expr 01 '>=' 1gibt true zurück, expr X01 '>=' X1kehrt false).
Stéphane Chazelas
7

Wenn Sie einen Ganzzahlvergleich durchführen möchten, verwenden Sie besser (()), wobei Sie auch> = usw. verwenden können.

Beispiel:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
Bollovan
quelle
Oder (( UID == 0 ))oder (( ! UID ))was das angeht. Beachten Sie, dass dies ((...))kein Standard ist (eine kshFunktion, die auch von bashund zshmit Variationen unterstützt wird).
Stéphane Chazelas