Каково различие между единственными и двойными знаками "равно" (=) в сравнениях оболочки?

Кроме проблем личинки выше (который я не испытал), необходимо знать об этой очень противной проблеме с некоторыми дисками (т.е.: модели УШЕЙ от WS): диск лжет о размере сектора

Используя один из тех дисков, необходимо удостовериться, что установка выровненная к 4K секторам вручную: так как диск лежит, fdisk не имеет никакого способа знать, что он должен выровняться на 4k секторах, и производительность будет ужасна (примерно в 10 раз хуже) при записи в диск, так как каждая 512-байтовая запись подвергнется чтению 4k, сопровождаемому записью 4k! (Ваша файловая система, вероятно, уже имеет 4k секторы), Некоторые недавние дистрибутивы могли бы быть лучше в ней теперь, но когда я купил ее, они не сделали..

29
22.03.2018, 13:14
3 ответа

[[ $a == $b ]] не сравнение, это - сопоставление с образцом. Вам нужно [[ $a == "$b" ]] для сравнения равенства от байта к байту. = совпадает с == в любой оболочке, которая поддерживает [[...]] (представленный ksh).

[[...]] не является стандартным sh синтаксис. [ команда является стандартной, и стандартный оператор сравнения, там = (хотя некоторые [ реализации также распознают ==).

Точно так же, как в любом аргументе любой команде, переменные расширения должны быть заключены в кавычки для предотвращения split+glob и пустого удаления (только последний, выполняемый в zsh), таким образом:

[ "$a" = "$b" ]

В стандарте sh, сопоставление с образцом, покончили case:

case $a in
  ($b) ...
esac

Для полноты другие подобные равенству операторы можно столкнуться в сценариях оболочки:

  • [ "$a" -eq "$b" ]: стандарт [ оператор для сравнения десятичных целых чисел. Некоторые [ реализации позволяют пробелы вокруг чисел, некоторые позволяют произвольные арифметические выражения, но это не портативно. Портативно, можно использовать [ "$((a))" -eq "$((b))" ] для этого.См. также [ "$((a == b))" -ne 0 ] который был бы стандартным эквивалентом (за исключением того, что POSIXly, поведение только указано если $a и $b содержите целочисленные константы):
  • ((a == b)), от ksh и также найденный в zsh и bash, возвращает true, если оценка арифметического выражения сохранила в $a приводит к тому же числу как число $b. Как правило, это используется для сравнения чисел. Обратите внимание, что существуют изменения между оболочками относительно того, как оценены арифметические выражения и какие числа поддерживаются (например, удар и некоторая реализация/версии 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 a strcoll() сравнение, это то, ли $a и $b отсортируйте то же.

См. также:

32
27.01.2020, 19:38

Они эквивалентны в ударе:

[[ $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: Каково различие между тестом, [и [[?.

14
27.01.2020, 19:38

И =, и ==являются операторами. В некоторых языках (, таких как C ), один используется для присвоения значения переменной, а другой — для сравнения значений (результата арифметических выражений ). На самом деле оба оператора точно такие же, как и внутри Arithmetic Evaluation. $((a=23))— это присваивание, $((a==23))— это арифметическое сравнение.

$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"
11 0 23 1

Но внутри тестовых конструкций (все операторы test и […] и [[…]])означают одно и то же. выполнить ту же операцию.

Итак, все эти варианты:

test "$a" =  "$b"
   [ "$a" =  "$b" ]
  [[ "$a" =  "$b" ]]
test "$a" == "$b"
   [ "$a" == "$b" ]
  [[ "$a" == "$b" ]]

Являются ли эквивалентными внутри bash для проверки двоичного равенства (переменных, цитируемых ). Если правая переменная не заключена в кавычки, она может быть интерпретирована как шаблон и сопоставлена ​​соответственно :как шаблон, а не как литеральная строка.

Приведенные в кавычках операторы \=и \==также эквивалентны при использовании в тесте и […]. Но цитируемый оператор \==терпит неудачу внутри [[…]].

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

3
27.01.2020, 19:38

Теги

Похожие вопросы