Je pense que la réponse que vous recherchez est implicite (sinon énoncée) par la réponse de Vinko , bien qu'elle ne soit pas énoncée simplement. Pour distinguer si VAR est défini mais vide ou non défini, vous pouvez utiliser:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Vous pouvez probablement combiner les deux tests de la deuxième ligne en un seul avec:
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Cependant, si vous lisez la documentation d'Autoconf, vous constaterez qu'ils ne recommandent pas de combiner les termes avec « -a
» et recommandent d'utiliser des tests simples séparés combinés avec &&
. Je n'ai pas rencontré de système présentant un problème; cela ne veut pas dire qu'ils n'existaient pas (mais ils sont probablement extrêmement rares de nos jours, même s'ils n'étaient pas aussi rares dans un passé lointain).
Vous pouvez trouver les détails de ceux-ci, ainsi que d'autres extensions de paramètres de shell connexes , la commande test
ou[
et les expressions conditionnelles dans le manuel Bash.
J'ai récemment été interrogé par e-mail sur cette réponse avec la question:
Vous utilisez deux tests, et je comprends bien le second, mais pas le premier. Plus précisément, je ne comprends pas la nécessité d'une expansion variable
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
Cela ne ferait-il pas la même chose?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
Bonne question - la réponse est «Non, votre alternative plus simple ne fait pas la même chose».
Supposons que j'écris ceci avant votre test:
VAR=
Votre test dira "VAR n'est pas du tout défini", mais le mien dira (par implication car il ne fait écho à rien) "VAR est défini mais sa valeur peut être vide". Essayez ce script:
(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:2 VAR is not set at all; fi
)
La sortie est:
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
Dans la deuxième paire de tests, la variable est définie, mais elle est définie sur la valeur vide. C'est la distinction que font les notations ${VAR=value}
et ${VAR:=value}
. Idem pour ${VAR-value}
et ${VAR:-value}
, et ${VAR+value}
et ${VAR:+value}
, et ainsi de suite.
Comme Gili le souligne dans sa réponse , si vous utilisez bash
l' set -o nounset
option, la réponse de base ci-dessus échoue unbound variable
. On y remédie facilement:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Ou vous pouvez annuler l' set -o nounset
option avec set +u
( set -u
équivalent à set -o nounset
).