Sim, eles são (quase) completamente equivalentes.
Detalhe
Dentro de uma construção [ … ]
:
O operador =
(ou mesmo a opção não posix de ==
) testa a correspondência de strings, não a correspondência de padrões.
Dentro de um [[ ]]
construct (do homem bash):
When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (==) or does not match (!=) the pattern, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string.
Dentro de um case
construct (do man bash, editado e ênfase meu):
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
... tries to match it against each pattern in turn, using the same matching rules as for pathname expansion (see Pathname Expansion below). … Each pattern examined is expanded using tilde expansion, parameter and variable expansion, arithmetic substitution, command substitution, and process substitution. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters.
Tanto Pattern Matching
como Pathname Expansion
são usados para indicar o mesmo dentro do manual bash.
A única diferença que posso ver no manual é:
'[[ … ]]' 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
Esse quote removal
não está explicitamente listado para a construção do caso.
Que funciona para corresponder exatamente isso (para o [[ … ]]
):
Any part of the pattern may be quoted to force it to be matched as a string.
Use isto para testar este último ponto (agora a variável é não um padrão):
case "$1" in
"$pattern") echo case match
esac
Por que quase?
-
extglob
implícito:Desde versão 4.3 do bash
When the ‘==’ and ‘!=’ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob shell option were enabled.
Isso significa que um padrão usado com a opção
extglob
não definida funcionará de maneira diferente em uma instrução case e dentro de uma construção[[
após a versão 4.3 do bash. -
|
implícito:A sintaxe do caso é:
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
O que significa que pode haver vários padrões separados por
|
(OR).Assim:
shopt -s extglob; p1="+([0-9])"; p2="+([abcde])" case "$1" in $p1|$p2) echo "or case match" ; ;; esac
Que corresponderá a uma sequência de apenas números ou apenas letras em
abcde
, como1234
ouaabee
, mas não12a
oub23
.Um
[[
funcionará de maneira equivalente se regex (veja em var p3) forem usados:#!/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