Quelle est la meilleure façon de déterminer si une variable en bash est vide ("")?
J'ai entendu dire qu'il est recommandé de faire if [ "x$variable" = "x" ]
Est-ce la bonne méthode? (il doit y avoir quelque chose de plus direct)
Quelle est la meilleure façon de déterminer si une variable en bash est vide ("")?
J'ai entendu dire qu'il est recommandé de faire if [ "x$variable" = "x" ]
Est-ce la bonne méthode? (il doit y avoir quelque chose de plus direct)
C'est vrai - j'allais recommander -s
, mais test -s ''
se termine par un 1, alors que test -z ''
nous donne le 0 anticipé.
En Bash, lorsque vous ne vous souciez pas de la portabilité vers les shells qui ne le prennent pas en charge, vous devriez toujours utiliser la syntaxe des doubles crochets :
N'importe lequel des éléments suivants :
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
En Bash, en utilisant des doubles crochets, les guillemets ne sont pas nécessaires. Vous pouvez simplifier le test pour une variable qui contient une valeur à :
if [[ $variable ]]
Cette syntaxe est compatible avec ksh (au moins ksh93, de toute façon). Elle ne fonctionne pas dans les shells Bourne purs de POSIX ou plus anciens comme sh ou dash.
Voir ma réponse ici et BashFAQ/031 pour plus d'informations sur les différences entre les doubles et simples crochets.
Vous pouvez tester pour voir si une variable est spécifiquement non définie (distincte d'une chaîne vide) :
if [[ -z ${variable+x} ]]
où le "x" est arbitraire.
Si vous voulez savoir si une variable est nulle mais non non définie :
if [[ -z $variable && ${variable+x} ]]
Cette if [[ $variable ]]
a bien fonctionné pour moi, et n'a même pas besoin du set -u
qui était requis par l'une des autres solutions proposées.
Pourquoi recommandez-vous une fonctionnalité non portable alors que cela n'apporte aucun bénéfice ?
Une variable dans bash (et tout shell compatible POSIX) peut être dans l'un des trois états :
La plupart du temps, vous avez seulement besoin de savoir si une variable est définie comme une chaîne non vide, mais parfois il est important de faire la distinction entre unset et défini comme une chaîne vide.
Voici des exemples de comment vous pouvez tester les différentes possibilités, et cela fonctionne dans bash ou tout shell compatible POSIX :
if [ -z "${VAR}" ]; then
echo "VAR est unset ou défini comme une chaîne vide"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR est unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR est défini comme une chaîne vide"
fi
if [ -n "${VAR}" ]; then
echo "VAR est défini comme une chaîne non vide"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR est défini, possiblement comme une chaîne vide"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR est soit unset soit défini comme une chaîne non vide"
fi
Voici la même chose mais sous forme de tableau pratique :
+-------+-------+-----------+
VAR est : | unset | vide | non vide |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | vrai | vrai | faux |
| [ -z "${VAR+set}" ] | vrai | faux | faux |
| [ -z "${VAR-unset}" ] | faux | vrai | faux |
| [ -n "${VAR}" ] | faux | faux | vrai |
| [ -n "${VAR+set}" ] | faux | vrai | vrai |
| [ -n "${VAR-unset}" ] | vrai | faux | vrai |
+-----------------------+-------+-------+-----------+
La construction ${VAR+foo}
se développe en une chaîne vide si VAR
est unset ou en foo
si VAR
est défini comme quelque chose (y compris une chaîne vide).
La construction ${VAR-foo}
se développe en la valeur de VAR
si défini (y compris si défini comme une chaîne vide) et foo
si unset. Cela est utile pour fournir des valeurs par défaut modifiables par l'utilisateur (par exemple, ${COLOR-red}
dit d'utiliser red
sauf si la variable COLOR
a été définie comme quelque chose).
La raison pour laquelle [ x"${VAR}" = x ]
est souvent recommandé pour tester si une variable est soit unset soit définie comme une chaîne vide, est que certaines implémentations de la commande [
(également connue sous le nom de test
) sont boguées. Si VAR
est défini comme quelque chose comme -n
, alors certaines implémentations feront une erreur lorsqu'on leur donne [ "${VAR}" = "" ]
, puisque le premier argument de [
est interprété à tort comme l'opérateur -n
, et non comme une chaîne.
Tester si une variable est définie avec une chaîne vide peut également se faire en utilisant [ -z "${VAR-set}" ]
.
Quelle est la différence entre le premier et le dernier construct? Ils correspondent tous les deux à "VAR n'est pas défini ou défini sur une chaîne non vide".
-z
est la meilleure façon.
Une autre option que j'ai utilisée est de définir une variable, mais elle peut être remplacée par une autre variable par exemple
export PORT=${MY_PORT:-5432}
Si la variable $MY_PORT
est vide, alors PORT
est défini sur 5432, sinon PORT est défini sur la valeur de MY_PORT
. Remarquez la syntaxe incluant le deux-points et le trait d'union.
SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.
1 votes
Voir : Test pour une chaîne de caractères de longueur non nulle en Bash sur StackOverflow.
2 votes
En Bash,
[[ -v VAR]]
est utilisé pour vérifier siVAR
est défini,[[ -z $VAR ]]
est utilisé pour vérifier si"$VAR"
est étendu à une chaîne vide (""
). Ainsi, vous pouvez utiliser[[ -v VAR && -z $VAR ]]
. En savoir plus ici (avec une référence officielle)0 votes
Connexe : [
[[
vs[
](https://unix.stackexchange.com/a/32211)