web-dev-qa-db-fra.com

Utiliser unset vs définir une variable à vide

J'écris actuellement un framework de test bash dans lequel, dans une fonction de test, des tests bash standard ([[) ainsi que des agents de correspondance prédéfinis peuvent être utilisés. Les correspondants sont des enveloppes de type [[] et, en plus de renvoyer un code retour, définissez un message significatif indiquant ce qui était attendu.

Exemple:

string_equals() {
    if [[ ! $1 = $2 ]]; then
            error_message="Expected '$1' to be '$2'."

            return 1
    fi
}

Ainsi, lorsqu'un matcher est utilisé et qu'il échoue, un message_erreur est alors défini.

Maintenant, à un moment donné, je vérifie si les tests ont réussi. Si cela réussit, j'imprime l'espérance en vert, si elle échoue en rouge.

De plus, il peut y avoir un ensemble error_message. Je vérifie donc si un message existe, l’imprime puis le désactive (car le test suivant peut ne pas définir un error_message):

if [[ $error_message ]]; then
    printf '%s\n' "$error_message"

    unset -v error_message
fi

Ma question est la suivante: s’il vaut mieux supprimer la variable, ou simplement la définir sur '', comme

error_message=''

Quel est le meilleur? Cela fait-il une différence? Ou peut-être devrais-je avoir un indicateur supplémentaire indiquant que le message a été défini?

95
helpermethod

Généralement, vous ne voyez pas de différence, sauf si vous utilisez set -u:

/home/user1> var=""
/home/user1> echo $var

/home/user1> set -u
/home/user1> echo $var

/home/user1> unset var
/home/user1> echo $var
-bash: var: unbound variable

Donc, vraiment, cela dépend de la façon dont vous allez tester la variable.

J'ajouterai que ma méthode de test préférée si elle est définie est:

[[ -n $var ]]  # True if the length of $var is non-zero

ou

[[ -z $var ]]  # True if zero length
133
cdarke

Comme il a été dit, l’utilisation de unset est différente avec les tableaux

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2
17
Steven Penny

Ainsi, en supprimant l'index de tableau 2, vous supprimez essentiellement cet élément du tableau et décrémentez sa taille (?).

J'ai fait mon propre test ..

foo=(5 6 8)
echo ${#foo[*]}
unset foo
echo ${#foo[*]}

Ce qui résulte en ..

3
0

Donc, juste pour clarifier que supprimer tout le tableau l’enlèvera en fait complètement.

2
PdC

Sur la base des commentaires ci-dessus, voici un test simple:

isunset() { [[ "${!1}" != 'x' ]] && [[ "${!1-x}" == 'x' ]] && echo 1; }
isset()   { [ -z "$(isunset "$1")" ] && echo 1; }

Exemple:

$ unset foo; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's unset
$ foo=     ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set
$ foo=bar  ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set
0
Sheljohn