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 xprefixo 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 $1está 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 -ae -opara 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 $1está vazia . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'- ambos retornam 0, mas no segundo caso $1não pode estar vazio porque não existe.
De acordo com http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , o -zteste 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.
shem alguns escritórios comerciais ainda têm o problema. Veja aqui para detalhes.