1056 votes

Comment déterminer si une variable de bash est vide?

Quelle est la meilleure façon de déterminer si une variable en bash est vide ("")?

J'ai entendu dire qu'il est recommandé de faire if [ "x$variable" = "x" ]

Est-ce la bonne méthode? (il doit y avoir quelque chose de plus direct)

1 votes

2 votes

En Bash, [[ -v VAR]] est utilisé pour vérifier si VAR est défini, [[ -z $VAR ]] est utilisé pour vérifier si "$VAR" est étendu à une chaîne vide (""). Ainsi, vous pouvez utiliser [[ -v VAR && -z $VAR ]]. En savoir plus ici (avec une référence officielle)

0 votes

1399voto

duffbeer703 Points 19867

Cela renverra true si une variable n'est pas définie ou est définie comme une chaîne vide ("").

if [ -z "${VAR}" ];

16 votes

Est-ce que cela inclut si une variable EST DÉFINIE à une valeur de "" ?

15 votes

Oui, ça le fait... "-z" teste pour une chaîne de longueur zéro.

0 votes

C'est vrai - j'allais recommander -s, mais test -s '' se termine par un 1, alors que test -z '' nous donne le 0 anticipé.

341voto

jason saldo Points 5036

En Bash, lorsque vous ne vous souciez pas de la portabilité vers les shells qui ne le prennent pas en charge, vous devriez toujours utiliser la syntaxe des doubles crochets :

N'importe lequel des éléments suivants :

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

En Bash, en utilisant des doubles crochets, les guillemets ne sont pas nécessaires. Vous pouvez simplifier le test pour une variable qui contient une valeur à :

if [[ $variable ]]

Cette syntaxe est compatible avec ksh (au moins ksh93, de toute façon). Elle ne fonctionne pas dans les shells Bourne purs de POSIX ou plus anciens comme sh ou dash.

Voir ma réponse ici et BashFAQ/031 pour plus d'informations sur les différences entre les doubles et simples crochets.

Vous pouvez tester pour voir si une variable est spécifiquement non définie (distincte d'une chaîne vide) :

if [[ -z ${variable+x} ]]

où le "x" est arbitraire.

Si vous voulez savoir si une variable est nulle mais non non définie :

if [[ -z $variable && ${variable+x} ]]

1 votes

Cette if [[ $variable ]] a bien fonctionné pour moi, et n'a même pas besoin du set -u qui était requis par l'une des autres solutions proposées.

5 votes

Je pense que c'est mieux que la réponse acceptée.

5 votes

Pourquoi recommandez-vous une fonctionnalité non portable alors que cela n'apporte aucun bénéfice ?

337voto

Richard Hansen Points 3530

Une variable dans bash (et tout shell compatible POSIX) peut être dans l'un des trois états :

  • unset
  • défini comme une chaîne vide
  • défini comme une chaîne non vide

La plupart du temps, vous avez seulement besoin de savoir si une variable est définie comme une chaîne non vide, mais parfois il est important de faire la distinction entre unset et défini comme une chaîne vide.

Voici des exemples de comment vous pouvez tester les différentes possibilités, et cela fonctionne dans bash ou tout shell compatible POSIX :

if [ -z "${VAR}" ]; then
    echo "VAR est unset ou défini comme une chaîne vide"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR est unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR est défini comme une chaîne vide"
fi
if [ -n "${VAR}" ]; then
    echo "VAR est défini comme une chaîne non vide"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR est défini, possiblement comme une chaîne vide"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR est soit unset soit défini comme une chaîne non vide"
fi

Voici la même chose mais sous forme de tableau pratique :

                        +-------+-------+-----------+
                VAR est : | unset | vide | non vide  |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | vrai  | vrai  | faux      |
| [ -z "${VAR+set}" ]   | vrai  | faux  | faux      |
| [ -z "${VAR-unset}" ] | faux  | vrai  | faux      |
| [ -n "${VAR}" ]       | faux  | faux  | vrai      |
| [ -n "${VAR+set}" ]   | faux  | vrai  | vrai      |
| [ -n "${VAR-unset}" ] | vrai  | faux  | vrai      |
+-----------------------+-------+-------+-----------+

La construction ${VAR+foo} se développe en une chaîne vide si VAR est unset ou en foo si VAR est défini comme quelque chose (y compris une chaîne vide).

La construction ${VAR-foo} se développe en la valeur de VAR si défini (y compris si défini comme une chaîne vide) et foo si unset. Cela est utile pour fournir des valeurs par défaut modifiables par l'utilisateur (par exemple, ${COLOR-red} dit d'utiliser red sauf si la variable COLOR a été définie comme quelque chose).

La raison pour laquelle [ x"${VAR}" = x ] est souvent recommandé pour tester si une variable est soit unset soit définie comme une chaîne vide, est que certaines implémentations de la commande [ (également connue sous le nom de test) sont boguées. Si VAR est défini comme quelque chose comme -n, alors certaines implémentations feront une erreur lorsqu'on leur donne [ "${VAR}" = "" ], puisque le premier argument de [ est interprété à tort comme l'opérateur -n, et non comme une chaîne.

3 votes

Tester si une variable est définie avec une chaîne vide peut également se faire en utilisant [ -z "${VAR-set}" ].

0 votes

@nwellnhof: Merci! J'ai mis à jour ma réponse pour utiliser la syntaxe plus concise.

0 votes

Quelle est la différence entre le premier et le dernier construct? Ils correspondent tous les deux à "VAR n'est pas défini ou défini sur une chaîne non vide".

47voto

mblsha Points 305

-z est la meilleure façon.

Une autre option que j'ai utilisée est de définir une variable, mais elle peut être remplacée par une autre variable par exemple

export PORT=${MY_PORT:-5432}

Si la variable $MY_PORT est vide, alors PORT est défini sur 5432, sinon PORT est défini sur la valeur de MY_PORT. Remarquez la syntaxe incluant le deux-points et le trait d'union.

2 votes

Par hasard trouvé cela aujourd'hui, et c'était exactement ce que je voulais. Merci! Je dois tolérer set -o nounset dans certains scripts.

25voto

MikeyB Points 38317

Si vous êtes intéressé par la distinction des cas de statut vide par rapport à non défini, regardez l'option -u pour bash :

$ set -u
$ echo $BAR
bash: BAR: variable non définie
$ [ -z "$BAR" ] && echo true
bash: BAR: variable non définie
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X