Может кто-нибудь объяснить разницу между -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 и поэтому не будут работать в других оболочках. Другие оболочки обычно не поддерживают [[...]] и ((...)) или ==.