Может кто-нибудь объяснить разницу между -eq
и ==
в bash скриптах?
Есть ли разница между следующими?
[ $a -eq $b ]
и [ $a == $b ]
Это просто, что ==
используется только тогда, когда переменные содержат числа?
Может кто-нибудь объяснить разницу между -eq
и ==
в bash скриптах?
Есть ли разница между следующими?
[ $a -eq $b ]
и [ $a == $b ]
Это просто, что ==
используется только тогда, когда переменные содержат числа?
Это наоборот: ==
для сравнения строк, -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-оболочек важна, используйте =
.
==
является bash -специальным псевдонимом для =
, и он выполняет сравнение строк (лексическое) вместо числового сравнения. eq
является числовым сравнением курса.
Наконец, я обычно предпочитаю использовать форму if [ "$a" == "$b" ]
Это зависит от 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 и поэтому не будут работать в других оболочках. Другие оболочки обычно не поддерживают [[...]]
и ((...))
или ==
.