Para o bem desta questão, suponha que o glob /a/b/c/*
não produz correspondências.
Isso significa que o teste a seguir deve falhar (em outras palavras, deve produzir um diferente de zero $?
):
[[ -n /a/b/c/*(#qN) ]]
Este é de fato o caso se eu executar o teste diretamente na linha de comando (zsh). No entanto, se eu fizer exatamente o mesmo teste em um script, ele será bem-sucedido, o que não é o comportamento pretendido.
Se eu executar o mesmo script com o -x
sinalizador, o rastreamento resultante mostra o teste como
[[ -n '/a/b/c/*(#qN)' ]]
Não entendo por que as aspas simples aparecem em torno do argumento de test; no código-fonte do script não há aspas.
Se o zsh inserir automaticamente essas aspas simples, isso explicaria por que o texto foi bem-sucedido.
Perguntas:
- por que há uma diferença entre as versões de linha de comando e de script dessa expressão?
- o que preciso fazer para que o teste (corretamente) falhe quando estiver no script?
Da
CONDITIONAL EXPRESSIONS
seção do manual do zsh:Em outras palavras, em seu script, onde a
extendedglob
opção não está definida,/a/b/c/*(#qN)
é tratada como uma string literal.Um idioma melhor (IMO) para verificar se um glob corresponde a qualquer arquivo é com:
Isso não requer
extendedglob
e esse caso especial de[[ -n ...(#qN) ]]
. E também é mais eficiente graças ao queY1
pára na primeira partida.Ele funciona passando a expansão glob para uma função anônima cujo corpo é a
(($#))
expressão aritmética que retorna true se o número de argumentos para essa função anônima for diferente de zero.Você pode estendê-lo para coisas como: