%20%D0%BF%D1%80%D0%B8%20%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B8%20%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%B5%D0%BA%3F.png)
Читал, что для сравнения строк внутри if
нужно использовать двойные квадратные скобки. В некоторых книгах говорится, что сравнение можно сделать с помощью =
. Но это работает ==
и с .
#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
echo "equal"
fi
Есть ли разница между =
и ==
в сравнении?
решение1
В bash
(как в ksh
том, откуда bash
скопирован этот синтаксис), [[ $a == $b ]]
это не сравнение, это сопоставление с образцом. Вам нужно [[ $a == "$b" ]]
для сравнения на равенство байт-байт. =
то же самое, что и ==
в любой оболочке, которая поддерживает [[...]]
.
[[...]]
не является стандартным sh
синтаксисом.[
командаявляется стандартным, и стандартсравнениеоператор есть =
(хотя некоторые [
реализации также распознают ==
¹).
Как и в любом аргументе любой команды, расширения переменных должны быть заключены в кавычки, чтобы предотвратитьсплит+глоби пустое удаление (только последнее выполняется в zsh
), поэтому:
[ "$a" = "$b" ]
В стандартном варианте sh
сопоставление с образцом выполняется с помощью case
:
case $a in
($b) ...
esac
Для полноты картины, другиеравенство-подобныйОператоры, которые вы можете встретить в скриптах оболочки:
[ "$a" -eq "$b" ]
: стандартный[
оператор для сравнения десятичных целых чисел. Некоторые[
реализации допускают пробелы вокруг чисел, некоторые допускают произвольные арифметические выражения, но это непереносимо. Переносимо,[ "$(($a))" -eq "$(($b))" ]
для этого можно использовать. См. также,[ "$((a == b))" -ne 0 ]
что будет стандартным эквивалентом (за исключением того, что в POSIX поведение указано только если$a
и$b
содержат целые константы):((a == b))
, из ksh и также найденный вzsh
иbash
, возвращает true, если оценка арифметического выражения, сохраненного в ,$a
дает то же число, что и$b
. Обычно это используется для сравнения чисел. Обратите внимание, что существуют различия между оболочками относительно того, как оцениваются арифметические выражения и какие числа поддерживаются (например, bash и некоторые реализации/версии ksh не поддерживают числа с плавающей точкой или обрабатывают числа с ведущими нулями как восьмеричные).expr "$a" = "$b"
выполняет сравнение чисел, если оба операнда распознаются как десятичные целые числа (некоторые допускают пробелы вокруг числа), а в противном случае проверяет, имеют ли два строковых операнда одинаковый порядок сортировки. Это также не сработает для значений$a
или$b
, которые являютсяexpr
операторами типа(
,substr
...awk -- 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b"
: если$a
и$b
распознаются как числа (по крайней мере, десятичные целые числа и числа с плавающей точкой, такие как 1.2, -1.5e-4, начальные и конечные пробелы игнорируются, некоторые также распознают шестнадцатеричные, восьмеричные или что-либо, распознаваемоеstrtod()
), то выполняется числовое сравнение. В противном случае, в зависимости от реализации, это либо сравнение строк побайтно, либо, как дляexpr
сравненияstrcoll()
, то есть, являются ли$a
и$b
сортируют то же самое.
Смотрите также:
- В чем разница между [[ $a == z* ]] и [ $a == z* ]?
- использование одинарных или двойных скобок - bash
¹ который включает GNU [
и [
встроенные ksh
, bash
, yash
, некоторые, хотя и не все ash
, оболочки на основе zsh
, однако следует отметить, что в zsh
,=cmd
специальный оператор расширения имени файла(раскрывается в тех же контекстах, что и ~user
is), который расширяется до пути соответствующей команды, так что там, если вы не отключите опцию equals
отключения этой функции, вам нужно будет написать ее [ "$a" '==' "$b" ]
, иначе вы получите ошибку, что =
команда не найдена. То же самое для[ "$string" '=~' "$regexp" ]
решение2
В bash они эквивалентны:
[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]
Первые две переменные $x не обязательно заключать в кавычки. Bash выполняет разбиение слов и расширение пути внутри [, но не внутри [[:
$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$
[[ $x = "$y" ]]
является сравнением строк, но [[ $x = $y ]]
представляет собой выражение сопоставления с образцом:
$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0
-eq предназначен только для использования с целыми числами:
$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0
Смотрите такжеBashFAQ/031: В чем разница между test, [ и [[ ?.
решение3
Оба оператора =
и ==
являются операторами. В некоторых языках (например, C) один используется для присвоения значения переменной, а другой — для сравнения значений (результатов арифметических выражений). Фактически, оба оператора являются именно такими внутри арифметической оценки. A $((a=23))
— это присвоение, a $((a==23))
— арифметическое сравнение.
$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"
11 0 23 1
Но внутри тестовых конструкций (всехтести[…]и[[…]]) оба оператора означают одно и то же и выполняют одну и ту же операцию.
Итак, все эти варианты:
test "$a" = "$b"
[ "$a" = "$b" ]
[[ "$a" = "$b" ]]
test "$a" == "$b"
[ "$a" == "$b" ]
[[ "$a" == "$b" ]]
Являютсяэквивалент внутриБашдля проверки бинарного равенства (переменные в кавычках). Если правая переменная не заключена в кавычки, она может быть интерпретирована как шаблон и сопоставлена соответствующим образом: как шаблон, а не как буквальная строка.
Операторы в кавычках \=
и \==
также эквивалентны при использовании в test и […]
. Но оператор в кавычках \==
не работает внутри [[…]]
.
Для других оболочек результаты различаются (правильный результат должен быть Y -
(true false), код выхода, отличный от 0 (true) и 1 (false), сообщается как сбой с помощью ¤
). Некоторые оболочки терпят неудачу с помощью - -
(код выхода всегда 1).
| dash ksh bash zsh
test a = "$b" | Y - Y - Y - Y -
[ a = "$b" ] | Y - Y - Y - Y -
[[ a = "$b" ]] | ¤ ¤ Y - Y - Y -
test a == "$b" | ¤ ¤ Y - Y - - -
[ a == "$b" ] | ¤ ¤ Y - Y - - -
[[ a == "$b" ]] | ¤ ¤ Y - Y - Y -
test a \= "$b" | Y - Y - Y - Y -
[ a \= "$b" ] | Y - Y - Y - Y -
[[ a \= "$b" ]] | ¤ ¤ Y - - - - -
test a \== "$b" | ¤ ¤ Y - Y - Y -
[ a \== "$b" ] | ¤ ¤ Y - Y - Y -
[[ a \== "$b" ]] | ¤ ¤ Y - - - - -
Все параметры работают в ksh, операторы в кавычках не работают в bash и zsh (внутри [[…]]
), а операторы без кавычек \=
и \==
также не работают в zsh (вне [[…]]
).