Существует несколько различий. По-моему, несколько самых важных:
[
встроенное в Bash и многих других современных оболочках. Встроенное [
подобно test
с дополнительным требованием закрытия ]
. builtins [
и test
подражайте функциональности /bin/[
и /bin/test
наряду с их ограничениями так, чтобы сценарии были бы назад совместимы. Исходные исполняемые файлы все еще существуют главным образом для соответствия POSIX и назад совместимости. Выполнение команды type [
в Bash указывает на это [
интерпретируется как встроенное по умолчанию. (Отметьте: which [
только ищет исполняемые файлы на ПУТИ и эквивалентен type -p [
)[[
не так совместимо, это будет не обязательно работать со что /bin/sh
точки к. Так [[
более современная опция Bash / Zsh / Ksh.[[
встроен в оболочку и не имеет требований прежней версии, Вы не должны волноваться о разделении слова на основе переменной IFS, чтобы испортить на переменных, которые оценивают к строке с пробелами. Поэтому Вы не должны действительно помещать переменную в двойные кавычки.По большей части остальное - просто некоторый более хороший синтаксис. Для наблюдения большего количества различий я рекомендую эту ссылку на ответ FAQ: Каково различие между тестом, [и [[?. На самом деле, если Вы серьезно относитесь к сценариям удара, я рекомендую читать всю Wiki, включая FAQ, Ловушки и Руководство. Экспериментальный участок от раздела руководства объясняет эти различия также, и почему автор (авторы) думает [[
лучший выбор, если Вы не должны волноваться о том, чтобы быть как портативное. Главные причины:
< >
с обратными косыми чертами для них, чтобы не быть оцененным как перенаправление ввода, которое может действительно испортить некоторый материал путем перезаписи файлов. Это снова возвращается к [[
быть встроенным. Если бы [(тест) внешняя программа, оболочка должна была бы сделать исключение в способе, которым это оценивает <
и >
только если /bin/test
называется, который действительно не имел бы смысла.Короче говоря:
[Встроенный удар
[[]] Ключевые слова удара
Ключевые слова: Ключевые слова вполне похожи на builtins, но основное различие - то, что специальные правила парсинга относятся к ним. Например, [встроенный удар, в то время как [[ключевое слово удара. Они оба используются для тестирования материала, но так как [[ключевое слово, а не встроенное, это извлекает выгоду из нескольких специальных правил парсинга, которые делают это намного легче:
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
Первый пример возвращает ошибку, потому что удар пытается перенаправить файл b к команде. Второй пример на самом деле делает то, к чему Вы ожидаете это. Символ <больше не имеет свое особое значение оператора File Redirection.
Источник: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments
Различия в поведении
Некоторые различия в Bash 4.3.11:
Расширение POSIX и Bash:
[
- это POSIX [[
- это расширение Bash¹, документированное по адресу: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs обычная команда 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 \ : То же, что и выше. \
требуется, иначе выполняется перенаправление, как для любой другой команды. Расширение Bash.
expr a \ / dev / null
: эквивалент POSIX², см .: https://stackoverflow.com/questions/21294867/how-to-test-strings-for- lexicographic-less-than-or-equal-in-bash / 52707989 # 52707989 &&
и ||
[[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 для каждой конструкции [[]]
, которую я видел.
Если вы используете ] [[]]
вы:
[
- это обычная команда со странным именем, никакой специальной семантики здесь нет. ¹ На основе эквивалентной конструкции [[...]]
в оболочке 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]
будет эквивалентным.
Одиночная скобка , т.е. []
является оболочкой 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