web-dev-qa-db-fra.com

Tester si une variable est vide dans un script Shell

J'ai vu la technique suivante utilisée plusieurs fois sur de nombreux shells différents, pour tester si une variable est vide:

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

Y a-t-il des avantages à utiliser ceci par rapport à la plus canonique if [ -z "$1" ]? Serait-ce un problème de portabilité?

27
rahmu

Certains shells historiques ont implémenté un analyseur très simple qui pourrait être confondu par des choses comme [ -n = "" ] où le premier opérande à = ressemble à un opérateur et l'analyserait comme [ -n = ] ou provoquer une erreur de syntaxe. Dans [ "x$1" = x"" ], le préfixe x garantit que x"$1" ne peut pas ressembler à un opérateur, et donc la seule façon dont Shell peut analyser ce test est de traiter = comme opérateur binaire.

Tous les shells modernes, et même la plupart des shells plus anciens encore en fonctionnement, suivent les règles POSIX qui exigent que toutes les expressions de test jusqu'à 4 mots soient analysées correctement. Donc [ -z "$1" ] est un bon moyen de tester si $1 est vide et [ "$x" = "$y" ] est un bon moyen de tester l'égalité de deux variables.

Même certains shells actuels peuvent être confondus avec des expressions plus longues, et quelques expressions sont en fait ambiguës, donc évitez d'utiliser le -a et -o opérateurs pour construire des tests booléens plus longs et utiliser à la place des appels séparés à [ et le Shell && et || opérateurs booléens.

Selon http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , le -z test est dangereux dans certaines implémentations , vraisemblablement lorsque des chaînes "intéressantes" comme "-o a=a" sont testés.

5
Ansgar Esztermann

Les tests ci-dessus provoqueront également une erreur si vous exécutez avec "set -u" ou "set -o nounset"

Une façon plus stable de vérifier une variable vide serait d'utiliser expansion des paramètres :

MYVAR = $ {MYVAR: - "Mauvaise valeur"}

Cette méthode fonctionne pour le bourne Shell traditionnel, ainsi que pour ksh et bash.

3
Scott Hoffman
    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
0
aslam mohammed