Test si une variable est vide dans un script shell

J'ai vu la technique suivante utilisée plusieurs fois sur plusieurs coquilles différentes, pour tester si une variable est vide:

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

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

Certains shells historiques implémentaient un parseur très simple qui pouvait être confondu par des choses comme [ -n = "" ] où le premier opérande à = ressemblait à un opérateur, et l'parsingrait comme [ -n = ] ou provoquerait une erreur de syntaxe. Dans [ "x$1" = x"" ] , le préfixe x garantit que x"$1" ne peut pas ressembler à un opérateur, donc la seule façon d'parsingr ce test est de traiter = tant qu'opérateur binary.

Toutes les coquilles modernes, et même la plupart des coquilles plus anciennes encore en activité, suivent les règles POSIX qui exigent que toutes les expressions de test de 4 mots maximum soient analysées correctement. Donc, [ -z "$1" ] est une façon appropriée de tester si $1 est vide , et [ "$x" = "$y" ] est un moyen approprié pour tester l'égalité de deux variables.

Même certaines shells actuelles peuvent être confondues avec des expressions plus longues, et quelques expressions sont en réalité ambiguës. Évitez donc d'utiliser les opérateurs -a et -o pour build des tests booleans plus longs et utilisez plutôt des appels distincts à [ et les propres && et || opérateurs booleans.

Selon http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , le test -z est peu sûr dans certaines implémentations , probablement lorsque des strings "intéressantes" comme "-oa=a" sont testés.

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

Une méthode plus stable pour vérifier une variable vide serait d'utiliser l' expansion des parameters :

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

Cette méthode fonctionne pour la shell de bourne traditionnelle, ainsi que ksh, et 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