Подтвердить что ты не робот

Bash Операторы равенства (==, -eq)

Может кто-нибудь объяснить разницу между -eq и == в bash скриптах?

Есть ли разница между следующими?

[ $a -eq $b ]  и [ $a == $b ]

Это просто, что == используется только тогда, когда переменные содержат числа?

4b9b3361

Ответ 1

Это наоборот: == для сравнения строк, -eq для числовых. -eq находится в том же семействе, что и -lt, -le, -gt, -ge и -ne, если это поможет вам запомнить, что есть.

$ [ a == a ]; echo $?
0
$ [ a -eq a ]; echo $?
-bash: [: a: integer expression expected
2

== является bash -ism. Форма POSIX =. Если переносимость не-w51-оболочек важна, используйте =.

Ответ 2

== является bash -специальным псевдонимом для =, и он выполняет сравнение строк (лексическое) вместо числового сравнения. eq является числовым сравнением курса.

Наконец, я обычно предпочитаю использовать форму if [ "$a" == "$b" ]

Ответ 3

Это зависит от Test Construct вокруг оператора. Ваши варианты - двойные скобки, двойные фигурные скобки, отдельные фигурные скобки или test

Если вы используете ((...)), вы тестируете арифметическое эквити с помощью ==, как в C:

$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1

(Примечание: 0 означает true в смысле Unix, а non zero - неудачный тест)

Использование -eq внутри двойной скобки является синтаксической ошибкой.

Если вы используете [...] (или одну скобку) или [[...]] (или двойная скобка) или test вы можете использовать один из -eq, -ne, -lt, -le, -gt или -ge как арифметическое сравнение.

$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0

== внутри одиночной или двойной фигурной скобки (или команды test) является одним из операторов сравнения строк:

$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1

Как строковый оператор, = эквивалентен == и отмечает пробелы вокруг = или == его требуемые.

Пока вы можете сделать [[ 1 == 1 ]] или [[ $(( 1+1 )) == 2 ]], он тестирует равенство строк, а не арифметическое равенство.

Итак, -eq дает результат, вероятно, ожидаемый, что целочисленное значение 1+1 равно 2, хотя RH является строкой и имеет конечное пространство:

$ [[ $(( 1+1 )) -eq  "2 " ]]; echo $?
0

В то время как сравнение строк одного и того же числа забирает конечное пространство, и поэтому сравнение строк не выполняется:

$ [[ $(( 1+1 )) ==  "2 " ]]; echo $?
1

И ошибочное сравнение строк может привести к полному неправильному ответу. "10" лексикографически меньше "2", поэтому сравнение строк возвращает true или 0. Многие из них укушены этой ошибкой:

$ [[ 10 < 2 ]]; echo $?
0

против правильного теста на 10 арифметически меньше 2:

$ [[ 10 -lt 2 ]]; echo $?
1

В комментариях возникает вопрос о технической причине, когда целое число -eq в строках возвращает True для строк, которые не совпадают:

$ [[ "yes" -eq "no" ]]; echo $?
0

Причина в том, что Bash untyped. -eq заставляет строки интерпретироваться как целые числа, если возможно, включая базовое преобразование:

$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0

И 0, если Bash считает, что это просто строка:

$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1

Итак, [[ "yes" -eq "no" ]] эквивалентно [[ 0 -eq 0 ]]

Последнее примечание. Многие из Bash конкретных расширений для тестовых конструкций не являются POSIX и поэтому не будут работать в других оболочках. Другие оболочки обычно не поддерживают [[...]] и ((...)) или ==.