60 votes

En Bash, comment puis-je tester si une variable est définie en mode "-u" ?

Je viens de découvrir set -u en bash et cela m'a aidé à trouver plusieurs bogues qui n'avaient pas été vus auparavant. Mais j'ai aussi un scénario où je dois tester si une variable est définie avant de calculer une valeur par défaut. La meilleure solution que j'ai trouvée est la suivante :

if [ "${variable-undefined}" == undefined ]; then
    variable="$(...)"
fi

ce qui fonctionne (tant que la variable n'a pas la valeur de chaîne de caractères undefined ). Je me demandais s'il existait un meilleur moyen ?

64voto

Ramon Points 3465

C'est ce que j'ai trouvé qui fonctionne le mieux pour moi, en m'inspirant des autres réponses :

if [ -z "${varname-}" ]; then
  ...
  varname=$(...)
fi

34voto

CodeGnome Points 25402

Ce qui ne marche pas : Test pour les chaînes de longueur nulle

Vous pouvez tester les chaînes de caractères non définies de plusieurs façons. L'utilisation du test conditionnel standard ressemble à ceci :

# Test for zero-length string.
[ -z "$variable" ] || variable='foo'

Cela ne fonctionnera pas avec set -u Cependant.

Ce qui marche : Attribution conditionnelle

Vous pouvez également utiliser l'affectation conditionnelle, qui est une méthode plus proche de Bash. Par exemple :

# Assign value if variable is unset or null.
: "${variable:=foo}"

En raison de la manière dont Bash gère l'expansion de cette expression, vous pouvez l'utiliser sans risque avec set -u sans obtenir une erreur "bash : variable : unbound variable".

11voto

Felix Leipold Points 269

Dans bash 4.2 et plus récent, il y a un moyen explicite de vérifier si une variable est définie, qui est d'utiliser -v. L'exemple de la question pourrait alors être implémenté comme ceci :

if [[ ! -v variable ]]; then
   variable="$(...)"
fi

Voir http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions

Si vous voulez seulement définir la variable, si elle n'est pas déjà définie, il est probablement préférable de faire quelque chose de ce genre :

variable="${variable-$(...)}"

Notez que cela ne permet pas de traiter une variable définie mais vide.

5voto

kevinarpe Points 2902

Les réponses ci-dessus ne sont pas dynamiques, par exemple, comment tester si la variable avec le nom "dummy" est définie ? Essayez ceci :

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

En rapport : Comment vérifier si une variable est définie dans Bash ?

1voto

efa Points 11

Malheureusement, [[ -v variable ]] n'est pas supporté dans les anciennes versions de bash (du moins pas dans la version 4.1.5 que j'ai sur Debian Squeeze)

Vous pouvez utiliser un sous-coquilleur comme dans l'exemple suivant :

if (true $variable)&>/dev/null; then
    variable="$(...)"
fi

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X