En Bash, comment tester si une variable est définie en “-u” mode
Je viens de découvrir set -u
en bash et il m'a aidé à trouver plusieurs inédits de bugs. Mais j'ai aussi un scénario où j'ai besoin de tester si une variable est définie avant le calcul de certaines valeur par défaut. Le meilleur que j'ai trouvé pour cela est la suivante:
if [ "${variable-undefined}" == undefined ]; then
variable="$(...)"
fi
qui fonctionne (tant que la variable n'a pas la valeur de la chaîne undefined
). Je me demandais si il y avait une meilleure façon?
Vous devez vous connecter pour publier un commentaire.
Ce qui Ne fonctionne pas: Test de Chaînes de Longueur Nulle
Vous pouvez tester undefined chaînes de plusieurs façons. En utilisant le standard de test conditionnel ressemble à ceci:
Cela ne fonctionnera pas avec
set -u
, cependant.Ce Qui Fonctionne: Cession Conditionnelle
Alternativement, vous pouvez utiliser cession conditionnelle, ce qui est un plus Bash-like façon de le faire. Par exemple:
En raison de la façon Bash gère l'expansion de cette expression, vous pouvez utiliser en toute sécurité avec cette
set -u
sans l'obtention d'un "bash: variable: unbound variable d'erreur".:
🙂:
faire ?:
est un alias de vrai: stackoverflow.com/questions/3224878/...: $COMMAND
permettrait d'évaluer à vrai quel que soit le résultat de la commande ? un peu comme- COMMAND
avec les makefiles ?:
fournit la coquille un moyen d'effectuer des agrandissements que de définir des valeurs sans avoir à utiliser plus détaillé des constructions comme les[[ -z "$variable" ]] || variable='foo'
. Vous avez également besoin d'elle dans les endroits où un simple commentaire ne serait pas analyser correctement, comme un vide d'action dans une instruction if-then commeif true; then; fi
(qui soulève-bash: syntax error near unexpected token `;'
), plutôt que deif true; then :; fi
(qui fonctionne sans erreurs).C'est ce que j'ai trouvé qui fonctionne le mieux pour moi, tirant son inspiration de l'autre répond:
"${varname- }"
et"${varname:- }"
œuvres? Je suis surpris de voir les premiers travaux.${varname:-foo}
étend àfoo
sivarname
est unset ou définir une chaîne de caractères vide;${varname-foo}
étend uniquement àfoo
sivarname
n'est pas définie.En bash 4.2 et versions plus récentes, il est de manière explicite à vérifier si une variable est définie, qui consiste à utiliser -v.
L'exemple de la question pourrait alors être mis en œuvre comme ceci:
Voir http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions
Si vous ne souhaitez définir la variable, si elle n'est pas déjà défini, vous êtes probablement mieux de faire quelque chose le long de ces lignes:
variable="${variable-$(...)}"
Notez que cela ne traite pas avec un définies, mais la variable vide.
-v
n'a pas été ajoutébash
jusqu'à la version 4.2.Les réponses ci-dessus ne sont pas dynamiques, par exemple, comment le test est variable avec le nom "dummy" est-il défini? Essayez ceci:
Connexes: Comment vérifier si une variable est définie en Bash?
[[ -n $var ]]
ou[[ $var ]]
au lieu de[ ! -z "$var" ]
? Aussi pour info Bash a un support pour la variable d'indirection depuis la v2, donc il n'est pas nécessaire pour les eval ici. E. g.is_var_defined(){ if (( $# != 1 )); then echo "Expected exactly one argument: variable name as string, e.g., 'my_var'" >&2; return 1; fi; [[ -n ${!1:- } ]]; }
Au début de votre script, vous pouvez définir vos variables avec une valeur vide
Puis
set -u
mode afin de le lancer à traverstest -z
, d'où cette question.Malheureusement
[[ -v variable ]]
n'est pas pris en charge dans les anciennes versions de bash (au moins pas dans la version 4.1.5 j'ai sur Debian Squeeze)Vous pouvez utiliser une sous-shell comme ceci :
Je ne sais pas comment loin en arrière ${var+valeur} est pris en charge, mais ça marche au moins aussi loin que 4.1.2. Les versions plus anciennes n'ont pas ${var+valeur}, ils n'avaient que ${var:+valeur}. La différence est que ${var:+valeur} sera seulement évaluer la "valeur" si $var est définie à une non vide chaîne, tandis que ${var+valeur} permettra également d'évaluer la "valeur" si $var est vide.
Sans [[ -v var ]] ou ${var+valeur} je pense que vous auriez à utiliser une autre méthode. Probablement un shell interne est exécuté test a été décrit dans une précédente réponse:
Si votre shell processus de "set-u" active déjà ça va être actif dans le shell interne est exécuté aussi bien sans la nécessité d'établir un "u" à nouveau, mais y compris dans le shell interne est exécuté de commande permet à la solution de fonctionne aussi si le parent n'a pas eu les "u" est activé.
(Vous pouvez aussi utiliser un autre processus comme "printenv" ou "env" pour tester la présence de la variable, mais ça ne fonctionne que si la variable est exporté.)