Li em algum lugar que em um script de shell a [..]
construção like por exemplo [ -e $HOME/temp ]
é compatível com POSIX. Enquanto a [[..]]
construção de script like [[ -e $HOME/temp ]]
não é.
Isso é verdade?
Além da conformidade com POSIX, há algo inerentemente vantajoso que [..] tem sobre [[..]]? Ou vice-versa?
Sim, o
[
utilitário também é conhecido comotest
padrão, você pode encontrar uma versão HTML de sua especificação POSIX 2024 no site do OpenGroup .Houve uma proposta para especificar ksh's
[[...]]
nash
linguagem POSIX , mas ela acabou sendo rejeitada (reduzida para apenas adicionar alguns operadores extras[
que são comuns à maioria das implementações).Você verá a seção de justificativa afirmando:
Algumas das diferenças relevantes entre
[[...]]
e[
:[[...]]
do que com[...]
(onde os operadores-a
/-o
estão realmente obsoletos, pois não podem ser usados de forma confiável), mas usar[ ... ] && [ ... ] || [ ... ]
é bom e não incorre em penalidades, pois[
é invariavelmente integrado, o que torna[[...]]
o próprio&&
/ redundante (e potencialmente confuso, pois as regras de precedência são diferentes do /||
do shell ).&&
||
[[ $string = $pattern ]]
faz, na verdade, correspondência de padrões em vez de comparação de igualdade. Isso também é redundante com acase
construção padrão e fonte de bugs, pois as pessoas tendem a pensar que é aceitável deixar variáveis sem aspas dentro[[...]]
(e geralmente é) e esquecem de fazer isso[[ $string1 = "$string2" ]]
ao comparar strings para igualdade.[[ $string =~ $pattern ]]
o que é feito de forma diferente dependendo do shell. O bash e alguns outros shells tomaram uma decisão infeliz de ter aspas influenciando a operação regex lá, o que é errado, pois a sintaxe regex não é compatível com a tokenização normal do shell (mais detalhes em Como armazenar a expressão regular em uma variável de shell evita problemas com aspas de caracteres que são especiais para o shell? e no bug do Austin Group mencionado acima). O builtin do zsh e do yash também[
tem um operador.=~
[[...]]
interpretam seus operandos como expressões aritméticas (o que torna as coisas como[[ $1 -eq $2 ]]
uma vulnerabilidade de injeção de comando na maioria dos shells (e causa surpresas quando os números começam com 0, o que os faz ser interpretados como octais em alguns shells). Enquanto POSIX requer que operandos para aqueles de[
sejam tratados como inteiros decimais .[[...]]
são específicas para a construção e variam de shell para shell, enquanto[
é apenas um comando simples, portanto, tratado como qualquer outro comando.Então
[
geralmente está tudo bem e, para citar POSIX, o verdadeiro problema é o uso incorreto dotest
comando ([
) .Contanto que você se lembre de citar variáveis e outras expansões (conforme necessário para todos os comandos, não apenas
[
) e não use os operadores binários obsoletos-a
(e), (ou) (e que não são necessários de qualquer maneira, uma vez que você não pode combinar mais de um teste), está tudo bem (e mais seguro ao fazer comparações numéricas).-o
(...)
[
[[...]]
pode ser melhor, pois pode tornar o código mais curto, pode permitir que alguém pule a citação de algumas expansões, mas isso é principalmente açúcar sintático, mas às custas de ter que aprender sintaxe extra e suas peculiaridades.