Eu recebo o que esperava ao fazer isso em bash
:
[ "a" == "a" ] && echo yes
Isso me deu yes
.
Mas quando faço isso zsh
, recebo o seguinte:
zsh: = not found
Por que o mesmo comando ( /usr/bin/[
) se comporta de maneira diferente em diferentes shells?
$PATH
pesquisa. e==
não é umatest
sintaxe válida para a/usr/bin/[
rota. Apenas=
está bem.Respostas:
Não está
/usr/bin/[
em nenhuma das conchas. Em Bash, você está usando o built-intest
/[
comando , e de forma semelhante em zsh .A diferença é que o zsh também tem uma
=
expansão : se=foo
expande para o caminho dofoo
executável. Isso significa que==
é tratado como tentar encontrar um comando chamado=
no seuPATH
. Como esse comando não existe, você recebe o erroque você viu (e, de fato, a mesma coisa aconteceria mesmo se você estivesse usando
/usr/bin/[
).Você pode usar
==
aqui se você realmente quiser. Isso funciona como o esperado no zsh:porque a citação impede a
=word
expansão em execução. Você também pode desativar aequals
opção comsetopt noequals
.No entanto, você estaria melhor:
=
, o teste de igualdade compatível com POSIX ; ou[[
condicionais com==
no Bash e no zsh . Em geral,[[
é apenas melhor e mais seguro, incluindo evitar esse tipo de problema (e outros) por ter regras especiais de análise.fonte
[
e[[
? (Pesquisando no Google[ vs [[
me dá resultados paravs
somente, LOL)[[
suporta uma ampla gama de testes nos dois casos e possui regras de análise personalizadas que evitam a necessidade de citar variáveis, operadores e assim por diante. Se você estiver usando especificamente o Bash ou o zsh, use[[
. Se você estiver escrevendo um script portátil, escreva no comando[
/ compatível com POSIXtest
(que pode ou não ser um comando real no sistema em execução).[[
lá e esquecer que[
existe.[[
é diferentemente capaz. tente isso com ele:for f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
.=
/==
é sem dúvida um caso em que[[
não é melhor do que[
, como[[ a == b ]]
é faz "a" coincidir com o "b" padrão e não é "a" igual a "b" como seria de esperar. Isso significa que você precisa escrever,[[ $a == "$b" ]]
por exemplo. Pelo menos, com o[
comando, se você souber como a análise de comandos funciona, você precisará escrevê-lo[ "$a" = "$b" ]
para impedir o operador split + glob como em outros comandos. Com isso em mente e se você não usar -a ou -o,[
é seguro nas implementações em conformidade com POSIX.E zsh e bash dão a mesma resposta (também
type
está embutida nos dois shells):fonte
[
é um comando interno do shell no bash e no zsh:Na documentação dos comandos internos do shell :
A documentação oficial (
$ help test
) permite apenas usar=
:Portanto, a expressão correta seria:
O que acontece é que o bash é um pouco menos rigoroso. O suporte ao
==
operador[
parece ser uma extensão do bash e não é recomendável usá-lo:Se você deseja usar
==
, use a[[
palavra-chave:Lembre-se de que
[[
é menos portátil (não é POSIX). Mas tanto o bash quanto o zsh suportam.fonte
Nos dois shells,
bash
ezsh
, o[
utilitário é um shell embutido. Esta é a implementação de shells dessa ferramenta, que é usada preferencialmente ao binário/usr/bin/[
. Os diferentes resultados encontrados são causados por diferentes implementações.Em
bash
, o[
utilitário aceitaCONDITIONAL EXPRESSIONS
como o[[
comando composto. De acordo com a página do homem bashs tanto=
e==
são válidos:Em
zsh
, o[
utilitário tenta implementar o POSIX e suas extensões onde estas são especificadas. Na especificação do utilitário de teste POSIX, não há==
operador definido.fonte