Risposte:
Alcune shell storiche hanno implementato un parser molto semplice che potrebbe essere confuso da cose come [ -n = "" ]dove il primo operando =assomiglia a un operatore e analizzarlo come [ -n = ]o causare un errore di sintassi. In [ "x$1" = x"" ], il xprefisso garantisce che x"$1"non può apparire come un operatore, e quindi l'unico modo in cui la shell può analizzare questo test è trattarlo =come un operatore binario.
Tutte le shell moderne, e anche le shell più vecchie ancora in uso, seguono le regole POSIX che impongono che tutte le espressioni di test fino a 4 parole vengano analizzate correttamente. Quindi [ -z "$1" ]è un modo corretto di verificare se $1è vuoto ed [ "$x" = "$y" ]è un modo corretto di verificare l'uguaglianza di due variabili.
Anche alcune shell correnti possono essere confuse con espressioni più lunghe, e alcune espressioni sono in realtà ambigue, quindi evita di usare gli operatori -ae -oper costruire test booleani più lunghi e usa invece chiamate separate e operatori [propri &&e ||booleani della shell .
[ -z "$1" ]è un modo corretto di verificare se $1è vuota . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'- entrambi restituiscono 0, ma nel secondo caso $1non possono essere vuoti perché non esistono.
Secondo http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , il -ztest non è sicuro in alcune implementazioni , presumibilmente quando "-o a=a"vengono testate stringhe "interessanti" come .
I test di cui sopra causeranno anche un errore se si esegue con "set -u" o "set -o nounset"
Un modo più stabile per verificare la presenza di una variabile vuota sarebbe utilizzare l' espansione dei parametri :
MYVAR = $ {MYVAR: - "Valore errato"}
Questo metodo funziona con la tradizionale shell bourne, nonché con ksh e 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
=contro rispetto -z, ora come.
shsu alcuni Unices commerciali hanno ancora il problema. Vedi qui per i dettagli.