Le code suivant se termine par une erreur de variable non liée. Comment résoudre ce problème, tout en continuant à utiliser le set -o
option de nounset ?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Le code suivant se termine par une erreur de variable non liée. Comment résoudre ce problème, tout en continuant à utiliser le set -o
option de nounset ?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
:-
vérifie si la variable est désactivée o vide. Si vous voulez vérifier sólo s'il n'est pas défini, utilisez -
: VALUE=${WHATEVER-}
. De plus, une façon plus lisible de vérifier si une variable est vide : if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
En outre, cela ne fonctionnera pas si $WHATEVER
ne contient que des espaces blancs - Voir ma réponse.
Vous devez citer les variables si vous voulez obtenir le résultat escompté :
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Test :
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
J'ai essayé et je suis surpris que cela fonctionne... Tout est correct sauf que selon "info bash"
, "${WHATEVER-}"
devrait avoir un ":"
(deux points) avant le "-"
(tiret) comme : "${WHATEVER:-}"
et "${WHATEVER+defined}"
doit être précédé de deux points. "+"
(plus) comme : "${WHATEVER:+defined}"
. Pour moi, cela fonctionne dans les deux sens, avec ou sans les deux-points. Sur certaines versions de 'nix, cela ne fonctionnera probablement pas sans inclure les deux-points, donc il faudrait probablement les ajouter.
Non, -
, +
, :+
et :-
sont toutes prises en charge. Les premiers détectent si la variable est set et la seconde détecte si elle est set o vide . De man bash
: "L'omission des deux points entraîne un test uniquement pour un paramètre qui n'est pas défini."
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 voulez qu'un script non interactif imprime une erreur et sorte si une variable est nulle 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 sorte :
$ [[ "${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 [
y ]
au lieu de [[
y ]]
ci-dessus, mais cette dernière est préférable dans Bash.
Notez ce que font les deux points ci-dessus. De la docs :
En d'autres termes, si les deux points sont inclus, l'opérateur vérifie à la fois l'existence du paramètre et le fait que sa valeur n'est pas nulle ; si les deux points sont omis, l'opérateur vérifie uniquement l'existence.
Il n'y a apparemment pas besoin de -n
o -z
.
En résumé, je peux typiquement utiliser [[ "${VAR:?}" ]]
. Dans les exemples, cela affiche une erreur et quitte si une variable est nulle ou non définie.
Non, -z
vérifie uniquement si le paramètre suivant est vide. -z
est juste un argument de la [
commande. L'expansion de la variable se produit avant [ -z
peut faire n'importe quoi.
Cela semble être la bonne solution, dans la mesure où elle ne génère pas d'erreur si $VAR n'est pas défini. @dolmen pouvez-vous fournir un exemple de cas où cela ne fonctionnerait pas ?
@dolmen ayant lu diverses ressources bash sur l'expansion des paramètres et trouvant les autres réponses trop compliquées, je ne vois rien de mal dans celle-ci. Donc votre "clarification", bien que techniquement correcte, semble plutôt inutile en pratique, à moins que vous ayez besoin de différencier unset vs empty. J'ai testé unset, empty et non-empty, (bash 4) et il a fait à peu près ce qui est annoncé à chaque fois.
Les comparaisons de chaînes doivent utiliser la norme (POSIX) =
opérateur, et non ==
pour faciliter la portabilité, et [
au lieu de [[
si possible.
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.