Bash: double jest równy vs -eq


47

Robię porównanie liczb całkowitych w bash (próbuję sprawdzić, czy użytkownik działa jako root) i znalazłem dwa różne sposoby:

Podwójna równość:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Rozumiem, że nie ma> = lub <= w bash, tylko -ge i -le, więc dlaczego jest taki, ==jeśli istnieje -eq?

Czy istnieje różnica w porównaniu obu stron?


3
Należy pamiętać, że wymagane są spacje w nawiasach:, [ $UID -eq 0 ]nie [ $UID -eq 0].
Gilles „SO- przestań być zły”

Odpowiedzi:


50

==jest bashspecyficznym aliasem dla =, który wykonuje porównanie łańcuchowe (leksykalne) zamiast -eqporównania numerycznego. (Odwrotnie od Perla: operatory tekstowe są numeryczne, a symboliczne leksykalne.)


Czy to oznacza, że ​​jeśli obie strony są liczbami całkowitymi, konwertuje obie strony na ciągi, a następnie je porównuje?
beatgammit,

5
Dokładniej jest na odwrót: wszystko jest ciągiem, -eqmówi, bashaby interpretować ciągi jako liczby całkowite (produkuje 0bez ostrzeżenia, jeśli ciąg nie jest liczbowy).
geekozaur

11
@tjameson Podam przykład: [ 01 -eq 1 ]ale [ 01 != 1 ].
Gilles „SO- przestań być zły”

3
Należy zauważyć, że ==jako [operatora nie jest standardowa i nie powinny być stosowane, nie atakujących specyficzne . Został on wprowadzony przez ksh i jest również obsługiwany przez zsh (choć pierwsze =trzeba zacytować), yash i [narzędzie GNU (i wszelkie takie narzędzia zaimplementowane jako skrypty ksh w niektórych systemach).
Stéphane Chazelas,

@geekosaur Otrzymuję ostrzeżenie od bash v4.3.42, jeśli mój ciąg nie jest liczbowy: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: hello: oczekiwane wyrażenie całkowite
Andrew Bainbridge

13

Aby rozwinąć odpowiedź Bollovana ...

Nie ma operatora >=lub <=operatora porównania dla ciągów. Ale możesz użyć ich z ((...))poleceniem arytmetycznym do porównania liczb całkowitych.

Można również korzystać z innych operatorów porównania string ( ==, !=, <, >, ale nie =), aby porównać liczby całkowite, jeśli ich używać wewnątrz ((...)).

Przykłady

  • Oba [[ 01 -eq 1 ]]i (( 01 == 1 ))porównuj liczby całkowite. Oba są prawdziwe.
  • Zarówno [[ 01 == 1 ]]i [ 01 = 1 ]robić porównań ciągów. Oba są fałszywe.
  • Zarówno (( 01 -eq 1 ))i (( 01 = 1 ))zwróci błąd.

Uwaga: Składnia [[...]]podwójnego nawiasu i składnia podwójnego nawiasu ((...))nie są obsługiwane przez wszystkie powłoki.


1
Zauważ, że (z wyjątkiem mksh/ zsh(z wyjątkiem trybu POSIX (choć nie jest to funkcja POSIX))) (( 010 == 10 ))zwróci false, ponieważ 010będzie traktowany jako liczba ósemkowa (8 w systemie dziesiętnym).
Stéphane Chazelas,

Należy zauważyć, że podczas gdy większość test/ [implementacje nie mają >=/ <=operatorzy ( yash„s [ma jednak), exprma takich operatorów, choć będzie to zrobić arytmetycznego porównania jeśli argumenty są rozpoznawane jako cyfry ( expr 01 '>=' 1zwraca True, expr X01 '>=' X1zwraca false).
Stéphane Chazelas,

7

Jeśli chcesz wykonać porównanie liczb całkowitych, lepiej użyj (()), gdzie możesz także użyć> = itd.

Przykład:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi

Albo (( UID == 0 ))czy (( ! UID ))dla tej kwestii. Pamiętaj, że ((...))jest to niestandardowe ( kshfunkcja obsługiwana również przez bashi zshz odmianami).
Stéphane Chazelas,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.