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 x
prefisso 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 -a
e -o
per 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 $1
non possono essere vuoti perché non esistono.
Secondo http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , il -z
test 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.
sh
su alcuni Unices commerciali hanno ancora il problema. Vedi qui per i dettagli.