variable - switch bash linux




Comment vérifier si une variable est définie dans Bash? (20)

Functions to check if variable is declared/unset

including empty $array=()


The following functions test if the given name exists as a variable

# The first parameter needs to be the name of the variable to be checked.
# (See example below)

var_is_declared() {
    { [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}

var_is_unset() {
    { [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;} 
}
  • By first testing if the variable is (un)set, the call to declare can be avoided, if not necessary.
  • If however $1 contains the name of an empty $array=() , the call to declare would make sure we get the right result
  • There's never much data passed to /dev/null as declare is only called if either the variable is unset or an empty array.

This functions would test as showed in the following conditions:

a;       # is not declared
a=;      # is declared
a="foo"; # is declared
a=();    # is declared
a=("");  # is declared
unset a; # is not declared

a;       # is unset
a=;      # is not unset
a="foo"; # is not unset
a=();    # is not unset
a=("");  # is not unset
unset a; # is unset

.

For more details

and a test script see my answer to the question "How do I check if a variable exists in bash?" .

Remarque: L'utilisation similaire de declare -p, comme il est également montré par la answer de , est vraiment une coïncidence. Sinon je l'aurais bien sûr crédité!answer

Comment savoir si une variable est définie dans Bash?

Par exemple, comment vérifier si l'utilisateur a donné le premier paramètre à une fonction?

function a {
    # if $1 is set ?
}

Le droit chemin

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

${var+x} est une extension de paramètre qui évalue à rien si var est unset, et substitue la chaîne x autrement.

Citations Digression

Les citations peuvent être omises (donc nous pouvons dire ${var+x} au lieu de "${var+x}" ) parce que cette syntaxe et cette utilisation garantissent que cela ne s'étendra qu'à quelque chose qui ne nécessite pas de guillemets. (qui ne contient aucun saut de mot, donc pas besoin de guillemets), ou à rien (ce qui donne [ -z ] , qui évalue commodément la même valeur (true) que [ -z "" ] aussi)).

Cependant, alors que les citations peuvent être omises en toute sécurité, et que cela n'était pas immédiatement évident pour tout le monde (il n'était même pas évident pour le premier auteur de cette explication de citations qui est aussi un codeur Bash majeur) avec des guillemets comme [ -z "${var+x}" ] , au très petit coût possible d'une pénalité de vitesse O (1). Le premier auteur a également ajouté ceci comme un commentaire à côté du code en utilisant cette solution donnant l'URL de cette réponse, qui inclut maintenant aussi l'explication de la raison pour laquelle les citations peuvent être omises en toute sécurité.

La mauvaise direction

if [ -z "$var" ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

En effet, il ne fait pas la distinction entre une variable qui n'est pas définie et une variable définie sur la chaîne vide. C'est-à-dire, si var='' , alors la solution ci-dessus produira incorrectement que var est unset.

Mais cette distinction est essentielle dans les situations où l'utilisateur doit spécifier une extension, ou une liste supplémentaire de propriétés, et que ne pas les spécifier par défaut à une valeur non vide, alors que la spécification de la chaîne vide devrait faire utiliser une extension ou une liste vide de propriétés supplémentaires.


Alors que la plupart des techniques indiquées ici sont correctes, bash 4.2 supporte un test réel de la présence d'une variable ( man bash ), plutôt que de tester la valeur de la variable.

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

C'est ce que j'utilise tous les jours:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}

Cela fonctionne bien sous Linux et Solaris jusqu'à bash 3.0.

bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1

En bash vous pouvez utiliser -v dans le [[ ]] builtin:

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR

Il y a plusieurs façons de le faire, l'une d'entre elles étant la suivante:

if [ -z "$1" ]

Cela réussit si $ 1 est nul ou non défini


J'utilise toujours celui-ci, basé sur le fait qu'il semble facile d'être compris par quiconque voit le code pour la toute première fois:

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

Et, si vous voulez vérifier si pas vide;

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi

C'est tout.


Je trouve toujours la table POSIX dans l' autre réponse lente à grok, alors voici mon point de vue:

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${VARIABLE-default} | $VARIABLE  |          ""           |       "default"       |
 = |  ${VARIABLE=default} | $VARIABLE  |          ""           | $(VARIABLE="default") |
 ? |  ${VARIABLE?default} | $VARIABLE  |          ""           |       exit 127        |
 + |  ${VARIABLE+default} | "default"  |       "default"       |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE  |       "default"       |       "default"       |
:= | ${VARIABLE:=default} | $VARIABLE  | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE  |       exit 127        |       exit 127        |
:+ | ${VARIABLE:+default} | "default"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

Notez que chaque groupe (avec et sans deux-points) a le même ensemble et les mêmes cas, donc la seule chose qui diffère est la façon dont les cas vides sont traités.

Avec le deux-points précédent, les cas vides et non - remplis sont identiques, donc je les utiliserais dans la mesure du possible (c'est-à-dire := , pas seulement = , parce que le cas vide est incohérent).

Rubriques:

  • définir les moyens VARIABLE est non vide ( VARIABLE="something" )
  • vide signifie que VARIABLE est vide / null ( VARIABLE="" )
  • Désactivé signifie que VARIABLE n'existe pas ( unset VARIABLE )

Valeurs:

  • $VARIABLE signifie que le résultat est la valeur d'origine de la variable.
  • "default" signifie que le résultat est la chaîne de remplacement fournie.
  • "" signifie que le résultat est nul (une chaîne vide).
  • exit 127 signifie que le script cesse d'être exécuté avec le code de sortie 127.
  • $(VARIABLE="default") signifie que le résultat est la valeur d'origine de la variable et que la chaîne de remplacement fournie est affectée à la variable pour une utilisation future.

Les réponses ci-dessus ne fonctionnent pas lorsque l'option Bash set -u est activée. En outre, ils ne sont pas dynamiques, par exemple, comment tester est variable avec le nom "dummy" est défini? Essaye ça:

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 relation: Dans Bash, comment tester si une variable est définie en mode "-u"


Lisez la section "Extension des paramètres" de la page de manuel bash . L'extension de paramètre ne fournit pas de test général pour la définition d'une variable, mais vous pouvez effectuer plusieurs opérations sur un paramètre s'il n'est pas défini.

Par exemple:

function a {
    first_arg=${1-foo}
    # rest of the function
}

définira first_arg égal à $1 s'il est affecté, sinon il utilise la valeur "foo". Si vous devez absolument prendre un seul paramètre, et qu'il n'y a pas de bonne valeur par défaut, vous pouvez sortir avec un message d'erreur quand aucun paramètre n'est donné:

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

(Notez l'utilisation de : comme une commande null, qui ne fait que développer les valeurs de ses arguments Nous ne voulons rien faire avec $1 dans cet exemple, juste exit si elle n'est pas définie)


Pour ceux qui cherchent à vérifier pour unset ou vide quand dans un script avec set -u :

if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi

La vérification régulière [ -z "$var" ] échouera avec var; unbound variable var; unbound variable si set -u mais [ -z "${var-}" ] expands en chaîne vide si var est unset sans défaut.


Pour vérifier la variable de chaîne non nulle / non nulle, c'est-à-dire si elle est définie, utilisez

if [ -n "$1" ]

C'est le contraire de -z . Je me trouve en utilisant -n plus de -z .


Pour voir si une variable est non vide, j'utilise

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

Les tests opposés si une variable est non définie ou vide:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

Pour voir si une variable est définie (vide ou non vide), j'utilise

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

Les tests opposés si une variable n'est pas définie:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments

Si var peut être un tableau, alors la substitution de paramètre [ -z "${var+x}" ] est incorrecte. Pour être vraiment sûr dans Bash, vous devez utiliser une syntaxe de tableau comme [ "${#var[@]}" = 0 ] , comme indiqué ci-dessous.

is-var-set () {
    results="\${var+x}=${var+x}\t\${#var[@]}=${#var[@]}"
    if [ -z "${var+x}" ] && [ "${#var[@]}" = 0 ]; then
        echo -e "$1: var's unset.\t$results"
    elif [ -n "${var+x}" ] && [ "${#var[@]}" != 0 ]; then
        echo -e "$1: var is set. \t$results"
    else
        echo -e "$1: Is var set? \t$results"
    fi
    unset var # so we don't have to do it everywhere else
}

Dans presque tous les cas, ils sont d'accord. La seule situation que j'ai trouvée où la méthode de tableau est plus précise est quand la variable est un tableau non vide avec la position 0 désactivée (par exemple, dans les tests 7 et A ci-dessous). Ce désaccord vient de $var étant raccourci pour ${var[0]} , donc [ -z "${var+x}" ] ne vérifie pas tout le tableau.

Voici mes cas de test.

unset var;      is-var-set 1 # var unset
var='';         is-var-set 2 # var[0] set to ''
var=foo;        is-var-set 3 # var[0] set to 'foo'
var=();         is-var-set 4 # var unset (all indices)
var=(foo);      is-var-set 5 # var[0] set to 'foo'
var=([0]=foo);  is-var-set 6 # var[0] set to 'foo'
var=([1]=foo);  is-var-set 7 # var[0] unset, but var[1] set to 'foo'
declare -a var; is-var-set 8 # var empty, but declared as an array
declare -A var; is-var-set 9 # var empty, but declared as an associative array
declare -A var  # Because is-var-set() conveniently unsets it
var=([xz]=foo); is-var-set A # var[xz] set to 'foo', but var's otherwise empty
declare -a var  # Demonstrate that Bash knows about var, even when there's
declare -A var; is-var-set B # apparently no way to just _check_ its existence

Voici la sortie.

1: var's unset. ${var+x}=       ${#var[@]}=0
2: var is set.  ${var+x}=x      ${#var[@]}=1
3: var is set.  ${var+x}=x      ${#var[@]}=1
4: var's unset. ${var+x}=       ${#var[@]}=0
5: var is set.  ${var+x}=x      ${#var[@]}=1
6: var is set.  ${var+x}=x      ${#var[@]}=1
7: Is var set?  ${var+x}=       ${#var[@]}=1
8: var's unset. ${var+x}=       ${#var[@]}=0
9: var's unset. ${var+x}=       ${#var[@]}=0
A: Is var set?  ${var+x}=       ${#var[@]}=1
./foo.sh: line 26: declare: var: cannot convert indexed to associative array
B: var's unset. ${var+x}=       ${#var[@]}=0

En somme:

  • ${var+x} syntaxe d'expansion des paramètres ${var+x} fonctionne aussi bien que la syntaxe des tableaux ${#var[@]} dans la plupart des cas, comme la vérification des paramètres des fonctions. La seule façon dont ce cas pourrait casser est si une future version de Bash ajoute un moyen de passer des tableaux à des fonctions sans convertir le contenu en arguments individuels.
  • La syntaxe des tableaux est requise pour les tableaux non vides (associatifs ou non) avec l'élément 0 non défini.
  • Neither syntax explains what's going on if declare -a var has been used without assigning even a null value somewhere in the array. Bash still distinguishes the case somewhere (as seen in test B above), so this answer's not foolproof. Fortunately Bash converts exported environment variables into strings when running a program/script, so any issues with declared-but-unset variables will be contained to a single script, at least if it's not sourcing other scripts.

Tu peux faire:

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}

Voici comment tester si un paramètre n'est pas défini ou vide ("Null") ou défini avec une valeur :

+--------------------+----------------------+-----------------+-----------------+
|                    |       parameter      |     parameter   |    parameter    |
|                    |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

Source: POSIX: Expansion des paramètres :

Dans tous les cas représentés par "substitut", l'expression est remplacée par la valeur affichée. Dans tous les cas affichés avec "assign", le paramètre est affecté à cette valeur, qui remplace également l'expression.


If you wish to test that a variable is bound or unbound, this works well, even after you've turned on the nounset option:

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi

[[ $foo ]]

Ou

(( ${#foo} ))

Ou

let ${#foo}

Ou

declare -p foo

if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

Bien que pour les arguments, il est normalement préférable de tester $ #, qui est le nombre d'arguments, à mon avis.

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

if [[ ${!xx[@]} ]] ; then echo xx is defined; fi




variables