Verifica se una variabile è vuota in uno script di shell


27

Ho visto la seguente tecnica utilizzata molte volte su molte shell diverse, per verificare se una variabile è vuota:

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

Ci sono dei vantaggi nell'usarlo più dei canonici if [ -z "$1" ]? Potrebbe essere un problema di portabilità?

Risposte:


17

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 .


3
Non sono solo conchiglie storiche . Alcuni ksh88 basati shsu alcuni Unices commerciali hanno ancora il problema. Vedi qui per i dettagli.
Stéphane Chazelas,

Questa affermazione non è corretta: [ -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.
Mikeserv,


3

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.


2
Credo che questo sia scritto come -> M = $ {M: - "Bad Value"}
Gyan il

0
    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

3
Ciao! Non sono sicuro di come questo risponda alla domanda, che chiede perché usare =contro rispetto -z, ora come.
Dhag,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.