Das man test
páginas:
-n STRING
the length of STRING is nonzero
STRING equivalent to -n STRING
-z STRING
the length of STRING is zero
Executando [ -n $foo ]
, [ -n ]
, [ -z $foo ]
, [ -z ]
, todos retornam true. Isso é apenas um valor de retorno desleixado? Uma variável não definida não é uma STRING. A omissão total de uma expressão também não. E mesmo que ESTIVESSE sendo de alguma forma "coagido" a um, não estou inclinado a pensar que seu comprimento possa ser zero e diferente de zero simultaneamente.
De fato, ambos
if [ -n ] && [ -z ]; then
echo 1;
fi
# AND
if [ -n $foo ] && [ -z $foo ]; then
echo 1;
fi
... ambos rendem "1"
. Por que? O que está acontecendo sob o capô aqui?
O problema
Você não entendeu como as condições de teste são analisadas.
O primeiro bash determina o número de argumentos:
[
e]
é falsotrue
, não importa o conteúdo do argumento;false
no caso de um argumento vazio ([ '' ]
)-z
e-n
requer um segundo argumento. Como não há nenhum no seu caso, eles não são tratados como-z
/-n
mas apenas como qualquer parte do conteúdo que resulta emtrue
.A solução
Você tem que citar suas variáveis (como você quase sempre deve fazer). Em seguida, uma variável vazia é vista como um argumento vazio em vez de apenas ser removida completamente.