Respostas:
Algumas shells históricas implementaram um analisador muito simples que poderia ficar confuso com coisas como [ -n = "" ]
onde o primeiro operando se =
parece com um operador e analisaria isso como [ -n = ]
ou causaria um erro de sintaxe. Em [ "x$1" = x"" ]
, o x
prefixo garante que x"$1"
não possa parecer um operador e, portanto, a única maneira pela qual o shell pode analisar esse teste é tratando =
como um operador binário.
Todos os shells modernos, e mesmo os shells mais antigos ainda em operação, seguem as regras POSIX que determinam que todas as expressões de teste de até 4 palavras sejam analisadas corretamente. Portanto, [ -z "$1" ]
é uma maneira adequada de testar se $1
está vazia e [ "$x" = "$y" ]
é uma maneira adequada de testar a igualdade de duas variáveis.
Mesmo alguns shells atuais podem se confundir com expressões mais longas, e algumas expressões são realmente ambíguas, portanto, evite usar os operadores -a
e -o
para construir testes booleanos mais longos, e use chamadas separadas para [
os operadores booleanos &&
e próprios do shell ||
.
[ -z "$1" ]
é uma maneira adequada de testar se $1
está vazia . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'
- ambos retornam 0, mas no segundo caso $1
não pode estar vazio porque não existe.
De acordo com http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , o -z
teste não é seguro em algumas implementações , presumivelmente quando "-o a=a"
são testadas seqüências de caracteres "interessantes" .
Os testes acima também causarão um erro se você executar com "set -u" ou "set -o nounset"
Uma maneira mais estável de verificar uma variável vazia seria usar a expansão de parâmetros :
MYVAR = $ {MYVAR: - "Valor inválido"}
Este método funciona para o shell bourne tradicional, bem como para o ksh e o bash.
function isBlank {
valueNoSpaces=$(echo "$@" | tr -d ' ')
if [ "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ]
then
echo true ;
else
echo "" ;
fi
}
#Test
if [ $(isBlank " ") ]
then
echo "isBlank \" \" : it's blank"
else
echo " isBlank \" \": it is not blank"
fi
if [ $(isBlank "abc") ]
then
echo "isBlank \"abc\" : it's blank"
else
echo "isBlank \"abc\" :it is not blank"
fi
if [ $(isBlank null) ]
then
echo "isBlank null : it's blank"
else
echo "isBlank null : it is not blank"
fi
if [ $(isBlank "") ]
then
echo "isBlank \"\" : it's blank"
else
echo "isBlank \"\" : it is not blank"
fi
#Result
isBlank " " : it's blank
isBlank "abc" :it is not blank
isBlank null : it's blank
isBlank "" : it's blank
=
versus -z
, agora como.
sh
em alguns escritórios comerciais ainda têm o problema. Veja aqui para detalhes.