Ответы:
Да, они (почти) полностью эквивалентны.
Внутри [ … ]
конструкции:
=
Оператор (или даже вариант не-POSIX из ==
) проверяет соответствие строки, а не соответствующий шаблон.
Внутри [[ ]]
конструкции (от человека Баш):
Когда используются операторы == и! =, Строка справа от оператора считается шаблоном и сопоставляется в соответствии с правилами, описанными ниже в разделе «Сопоставление с шаблоном» . Если включена опция оболочки nocasematch , сопоставление выполняется без учета буквенных символов. Возвращаемое значение равно 0, если строка соответствует (==) или не соответствует (! =) Шаблону, и 1 в противном случае. Любая часть шаблона может быть заключена в кавычки, чтобы ее можно было сопоставить как строку.
Внутри case
конструкции (от man bash, отредактировано и выделено мое):
регистр слов в списке [[(] pattern [| pattern] ...) ;; ] ... esac
... пытается сопоставить его с каждым шаблоном по очереди, используя те же правила сопоставления, что и при расширении пути (см. Расширение пути ниже). … Каждый проверенный шаблон расширяется с использованием расширения тильды, расширения параметров и переменных, арифметического замещения, подстановки команд и замещения процесса. Если включена опция оболочки nocasematch , сопоставление выполняется без учета буквенных символов.
Оба Pattern Matching
и Pathname Expansion
используются, чтобы означать то же самое в руководстве по bash.
Единственное отличие, которое я вижу в руководстве:
`[[ … ]]` case
tilde expansion tilde expansion
parameter and variable expansion parameter and variable expansion
arithmetic expansion arithmetic substitution
command substitution command substitution
process substitution process substitution
quote removal
Это quote removal
явно не указано для конструкции case.
Который работает, чтобы точно соответствовать этому (для [[ … ]]
):
Любая часть шаблона может быть заключена в кавычки, чтобы ее можно было сопоставить как строку.
Используйте это, чтобы проверить эту последнюю точку (теперь переменная не является шаблоном):
case "$1" in
"$pattern") echo case match
esac
Неявный extglob
:
Начиная с версии 4.3 Bash
Когда используются операторы '==' и '! =', Строка справа от оператора считается шаблоном и сопоставляется в соответствии с правилами, описанными ниже в разделе «Сопоставление с образцом» , как если бы была включена опция оболочки extglob .
Это означает, что шаблон, используемый с опцией extglob
unset, будет работать по-разному в операторе case и внутри [[
конструкции после bash версии 4.3.
Неявный |
:
Синтаксис для case:
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
Это означает, что может быть несколько шаблонов, разделенных |
(ИЛИ).
Как это:
shopt -s extglob; p1="+([0-9])"; p2="+([abcde])"
case "$1" in
$p1|$p2) echo "or case match" ; ;;
esac
Который будет соответствовать либо строке только цифр или только букв abcde
, как 1234
или aabee
, но не 12a
или b23
.
A [[
будет работать аналогично, если используется регулярное выражение (смотрите var p3):
#!/bin/bash
shopt -s extglob ### Use extended globbing.
shopt -s globasciiranges ### The range [a-z] will expand to [abcdefghijklmnopqrstuvwxyz].
pattern="+([0-9])"
p1="+([0-9])"
p2="+([a-z])"
p3="^([0-9]+|[a-z]+)$"
case "$1" in
$pattern) echo case1 match ; ;&
$p1|$p2) echo case2 match ; ;;
esac
[[ "$1" == $pattern ]] && echo if1 match
[[ "$1" =~ $p3 ]] && echo if2 match
shopt
настроек и значений$1
илиpattern
, ни$?
впоследствии. Единственное отличие состоит в том, что$1
при работе под ним не раскрывается выводxtrace
.