web-dev-qa-db-fra.com

Teste si une variable est définie dans bash avec "set -o nounset"

Le code suivant se termine avec une erreur de variable non liée. Comment résoudre ce problème, tout en utilisant l'option set -o nounset?

#!/bin/bash

set -o nounset

if [ ! -z ${WHATEVER} ];
 then echo "yo"
fi

echo "whatever"
70
vinodkone
#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

if [ ! -z ${VALUE} ];
 then echo "yo"
fi

echo "whatever"

Dans ce cas, VALUE finit par être une chaîne vide si WHATEVER n'est pas défini. Nous utilisons l'extension {parameter:-Word}, que vous pouvez rechercher dans man bash sous "Extension des paramètres".

67
Angelom

Vous devez citer les variables si vous voulez obtenir le résultat attendu:

check() {
    if [ -n "${WHATEVER-}" ]
    then
        echo 'not empty'
    Elif [ "${WHATEVER+defined}" = defined ]
    then
        echo 'empty but defined'
    else
        echo 'unset'
    fi
}

Tester:

$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER='   '
$ check
not empty
26
l0b0

Hypothèses:

$ echo $Shell
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset

Si vous souhaitez qu'un script non interactif imprime une erreur et quitte si une variable est null ou non définie:

$ [[ "${HOME:?}" ]]

$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set

$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set

Si vous ne voulez pas que le script se termine:

$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."

$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

Vous pouvez même utiliser [ et ] au lieu de [[ et ]] ci-dessus, mais ce dernier est préférable dans Bash.

Notez ce que les deux points font ci-dessus. De la docs :

Autrement dit, si les deux points sont inclus, l’opérateur teste l’existence des deux paramètres et que sa valeur n’est pas nulle; si les deux points sont omis, l’opérateur vérifie uniquement son existence.

Il n'y a apparemment aucun besoin de -n ou -z.

En résumé, je peux généralement simplement utiliser [[ "${VAR:?}" ]]. Selon les exemples, cela affiche une erreur et se ferme si une variable est nulle ou non définie.

5
A-B-B

Que diriez-vous d'un oneliner?

[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"

-z vérifie les variables vides ou non définies

4
NublaII

Vous pouvez utiliser 

if [[ ${WHATEVER:+$WHATEVER} ]]; then

mais

if [[ "${WHATEVER:+isset}" == "isset" ]]; then

pourrait être plus lisible.

2
Aleš Friedl

Bien que ce ne soit pas exactement le cas d'utilisation demandé ci-dessus, j'ai constaté que si vous souhaitez utiliser nounset (ou -u), le comportement par défaut est celui que vous souhaitez: quitter un non descriptif avec un message descriptif.

Il m'a fallu assez de temps pour réaliser cela et j'ai compris que cela valait la peine d'être affiché comme solution.

Si tout ce que vous voulez, c'est faire écho à quelque chose d'autre lorsque vous quittez ou effectuez un nettoyage, vous pouvez utiliser un piège.

L'opérateur :- est probablement ce que vous voulez sinon.

0
Max Bileschi