Testando se uma variável está vazia em um shell script

23

Eu vi a seguinte técnica usada muitas vezes em muitos shells diferentes, para testar se uma variável está vazia:

if [ "x$1" = "x" ]; then 
    # Variable is empty
fi

Existe alguma vantagem em usar isso sobre o mais canônico if [ -z "$1" ] ? Poderia ser um problema de portabilidade?

    
por rahmu 20.02.2012 / 11:28

4 respostas

16

Alguns shells históricos implementaram um analisador muito simples que poderia ficar confuso com coisas como [ -n = "" ] , em que o primeiro operando para = se parece com um operador e analisaria isso como [ -n = ] ou causaria um erro de sintaxe. Em [ "x$1" = x"" ] , o prefixo x garante que x"$1" não possa ser semelhante a um operador e, portanto, a única maneira de o shell analisar esse teste é tratar = como um operador binário.

Todas as shells modernas, e até mesmo as mais antigas ainda em operação, seguem as regras POSIX que exige que todas as expressões de teste de até 4 palavras sejam analisadas corretamente. Portanto, [ -z "$1" ] é uma maneira apropriada de testar se $1 está vazio e [ "$x" = "$y" ] é uma maneira apropriada 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, evite usar os operadores -a e -o para construir testes booleanos mais longos e, em vez disso, use chamadas separadas para [ e os operadores booleanos && e || do próprio shell.

    
por 21.02.2012 / 02:59
5

De acordo com o link , o teste -z é inseguro em algumas implementações , presumivelmente quando strings "interessantes" como "-o a=a" são testadas.

    
por 20.02.2012 / 12:20
2

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 o parâmetro expansão :

MYVAR = $ {MYVAR: - "Valor inválido"}

Este método funciona para o shell bourne tradicional, assim como ksh e bash.

    
por 26.04.2012 / 20:00
-1
    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
    
por 28.08.2015 / 22:00