Dans le bash
shell, ${!var}
est une indirection variable. Il se développe à la valeur de la variable dont le nom est conservé $var
.
L'expansion de variable ${var+value}
est une extension POSIX qui se développe value
si la variable var
est définie (que sa valeur soit vide ou non).
La combinaison de ces derniers ${!var+x}
se développerait x
si la variable dont le nom est conservé $var
est définie.
Exemple:
$ foo=hello
$ var=foo
$ echo "${!var+$var is set, its value is ${!var}}"
foo is set, its value is hello
$ unset foo
$ echo "${!var+$var is set, its value is ${!var}}"
(ligne vide en sortie)
La fonction dans la question pourrait être réduite à
check_if_variable_is_set () { [ -n "${!1+x}" ]; }
ou même:
check_if_variable_is_set () { [ -v "$1" ]; }
ou même:
check_if_variable_is_set()[[ -v $1 ]]
Où -v
est un bash
test sur un nom de variable qui sera vrai si la variable nommée est définie, et faux sinon.
POSIX, il pourrait s'écrire:
check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }
Notez que ce sont toutes des vulnérabilités potentielles d'injection de commandes si l'argument de cette fonction pourrait finir par être sous le contrôle d'un attaquant. Essayez par exemple avec check_if_variable_is_set 'a[$(id>&2)]'
.
Pour éviter cela, vous pouvez d'abord vérifier que l'argument est un nom de variable valide. Pour les variables:
check_if_variable_is_set() {
case $1 in
("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
(*) eval '[ -n "${'"$1"'+x}" ]'
esac
}
(notez que [[:alpha:]]
cela vérifiera les caractères alphabétiques dans votre région tandis que certains shells n'acceptent que les caractères alphabétiques du jeu de caractères portable dans leur variable)