Каково различие между двойными и единственными квадратными скобками в ударе?

Оказывается, что необходимо установить новый стиль материал DFS на Server 2008 также для создания этой работы. Проблема решена...

435
задан 10 August 2009 в 00:11
5 ответов

Существует несколько различий. По-моему, несколько самых важных:

  1. [ встроенное в Bash и многих других современных оболочках. Встроенное [ подобно test с дополнительным требованием закрытия ]. builtins [ и test подражайте функциональности /bin/[ и /bin/test наряду с их ограничениями так, чтобы сценарии были бы назад совместимы. Исходные исполняемые файлы все еще существуют главным образом для соответствия POSIX и назад совместимости. Выполнение команды type [ в Bash указывает на это [ интерпретируется как встроенное по умолчанию. (Отметьте: which [ только ищет исполняемые файлы на ПУТИ и эквивалентен type -p [)
  2. [[ не так совместимо, это будет не обязательно работать со что /bin/sh точки к. Так [[ более современная опция Bash / Zsh / Ksh.
  3. Поскольку [[ встроен в оболочку и не имеет требований прежней версии, Вы не должны волноваться о разделении слова на основе переменной IFS, чтобы испортить на переменных, которые оценивают к строке с пробелами. Поэтому Вы не должны действительно помещать переменную в двойные кавычки.

По большей части остальное - просто некоторый более хороший синтаксис. Для наблюдения большего количества различий я рекомендую эту ссылку на ответ FAQ: Каково различие между тестом, [и [[?. На самом деле, если Вы серьезно относитесь к сценариям удара, я рекомендую читать всю Wiki, включая FAQ, Ловушки и Руководство. Экспериментальный участок от раздела руководства объясняет эти различия также, и почему автор (авторы) думает [[ лучший выбор, если Вы не должны волноваться о том, чтобы быть как портативное. Главные причины:

  1. Вы не должны волноваться о заключении в кавычки левой стороны теста так, чтобы это на самом деле было считано как переменная.
  2. Вы не должны выходить из меньше, чем и больше, чем < > с обратными косыми чертами для них, чтобы не быть оцененным как перенаправление ввода, которое может действительно испортить некоторый материал путем перезаписи файлов. Это снова возвращается к [[ быть встроенным. Если бы [(тест) внешняя программа, оболочка должна была бы сделать исключение в способе, которым это оценивает < и > только если /bin/test называется, который действительно не имел бы смысла.
314
ответ дан 28 November 2019 в 19:13
  • 1
    Спасибо, ссылка на удар, FAQ был тем, что я искал (не знал о той странице, спасибо). –  0x89 10 August 2009 в 01:07

На основе быстрого чтения соответствующих разделов страницы справочника главная разница, кажется, что == и != операторы соответствуют против шаблона, а не литеральной строки, и также что существует =~ оператор сравнения regex.

4
ответ дан 28 November 2019 в 19:13

Короче говоря:

[Встроенный удар

[[]] Ключевые слова удара

Ключевые слова: Ключевые слова вполне похожи на builtins, но основное различие - то, что специальные правила парсинга относятся к ним. Например, [встроенный удар, в то время как [[ключевое слово удара. Они оба используются для тестирования материала, но так как [[ключевое слово, а не встроенное, это извлекает выгоду из нескольких специальных правил парсинга, которые делают это намного легче:

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

Первый пример возвращает ошибку, потому что удар пытается перенаправить файл b к команде. Второй пример на самом деле делает то, к чему Вы ожидаете это. Символ <больше не имеет свое особое значение оператора File Redirection.

Источник: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments

134
ответ дан 28 November 2019 в 19:13

Различия в поведении

Некоторые различия в Bash 4.3.11:

  • Расширение POSIX и Bash:

  • обычная команда vs магия

    • [ - это просто обычная команда со странным именем.

      ] - это просто аргумент [, который предотвращает использование дальнейших аргументов.

      Ubuntu 16.04 фактически имеет исполняемый файл для него в / usr / bin / [, предоставленный coreutils, но встроенная версия bash имеет приоритет.

      Ничего не изменилось в способе синтаксического анализа Bash. команда.

      В частности, < - перенаправление, && и || объединяют несколько команд, () генерирует подоболочки, если экранировано с помощью \ , и расширение слова происходит как обычно.

    • [[X]] - это единственная конструкция, которая заставляет X анализироваться волшебным образом. <, && , || и () обрабатываются особым образом, и правила разделения слов другие.

      Также существуют другие отличия, такие как = и = ~ .

      На языке Bashese: [ - встроенная команда, а [[] - ключевое слово: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • && и ||

    • [[a = a && b = b]] : верно, логично и
    • [a = a && b = b] : синтаксическая ошибка, && проанализировано как разделитель команд И cmd1 && cmd2
    • [a = a -a b = b] : эквивалентно, но не рекомендуется в POSIX³
    • [a = a] && [b = b] : POSIX и надежный эквивалент
  • (

    • [[(a = a || a = b) && a = b]] : ложь
    • [(a = a)] : синтаксическая ошибка, () интерпретируется как подоболочка
    • [\ (a = a -oa = b \) -aa = b] : эквивалентно, но () устарел в POSIX
    • {[a = a ] || [а = б]; } && [a = b] Эквивалент POSIX 5
  • разделение слов и создание имени файла при расширении (split + glob)

    • x = 'a b'; [[$ x = 'a b']] : верно, кавычки не нужны
    • x = 'a b'; [$ x = 'a b'] : синтаксическая ошибка, заменяется на [a b = 'a b']
    • x = '*'; [$ x = 'a b'] : синтаксическая ошибка, если в текущем каталоге более одного файла.
    • x = 'a b'; ["$ x" = 'a b'] : эквивалент POSIX
  • =

    • [[ab = a? ]] : true, потому что он выполняет сопоставление с образцом ( *? [ являются магическими). Не расширяется на файлы в текущем каталоге.
    • [ab = a? ] : глобус? расширяется. Это может быть истина или ложь в зависимости от файлов в текущем каталоге.
    • [ab = a \? ] : false, а не расширение глобуса
    • = и == одинаковы в [ и [[], но == является расширением Bash.
    • case ab в (a?) Echo match; esac : эквивалент POSIX
    • [[ab = ~ 'ab?' ]] : false 4 , теряет магию с ''
    • [[ab? = ~ 'ab?' ]] : истина
  • = ~

    • [[ab = ~ ab? ]] : верно,POSIX расширенное регулярное выражение соответствует, ? не раскрывает глобус
    • [a = ~ a] : синтаксическая ошибка. Нет эквивалента в bash.
    • printf 'ab \ n' | grep -Eq 'ab?' : эквивалент POSIX (только однострочные данные)
    • awk 'BEGIN {exit! (ARGV [1] ~ ARGV [2])}' ab 'ab?' : Эквивалент POSIX.

Рекомендация : всегда используйте [].

Существуют эквиваленты POSIX для каждой конструкции [[]] , которую я видел.

Если вы используете ] [[]] вы:

  • теряете переносимость
  • вынуждают читателя изучить тонкости другого расширения bash. [ - это обычная команда со странным именем, никакой специальной семантики здесь нет.

¹ На основе эквивалентной конструкции [[...]] в оболочке Korn

², но не выполняется для некоторых значений a или b (например, + или index ) и выполняет числовое сравнение, если a и b выглядят как десятичные целые числа. expr "x $ a" '<' "x $ b" работает с обоими.

³, а также не работает для некоторых значений a или b например ! или (.

4 в bash 3.2 и более поздних версиях и при условии, что совместимость с bash 3.1 не включена (например, с BASH_COMPAT = 3.1 )

5 , хотя группировка (здесь с группой команд {...;} вместо (...) , которая запускала бы ненужную подоболочку) не требуется, поскольку операторы оболочки || и && (в отличие от || и && [[.. .]] операторы или -o / -a [ операторы) имеют одинаковый приоритет. Итак, [a = a] || [a = b] && [a = b] будет эквивалентным.

81
ответ дан 28 November 2019 в 19:13

Одиночная скобка , т.е. [] является оболочкой POSIX, совместимой с заключением условного выражения.

Двойные скобки , т.е. [[]] - это улучшенная (или расширенная) версия стандартной версии POSIX, это поддерживается bash и другими оболочками (zsh, ksh).

В bash, для числового сравнения мы используем eq , ne , lt и gt , с двойными скобками для сравнения мы можем использовать == , ! = , <, и > буквально.

  • [ - синоним тестовой команды. Даже если он встроен в оболочку, он создает новый процесс.
  • [[ - это новая улучшенная версия, которая является ключевым словом, а не программой.

например:

[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory 
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
6
ответ дан 28 November 2019 в 19:13

Теги

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