En el bash
shell, ${!var}
es una indirección variable. Se expande al valor de la variable cuyo nombre se mantiene $var
.
La expansión de la variable ${var+value}
es una expansión POSIX que se expande value
si la variable var
está configurada (no importa si su valor está vacío o no).
Combinando estos, ${!var+x}
se expandiría a x
si se establece la variable cuyo nombre se mantiene $var
.
Ejemplo:
$ 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}}"
(línea vacía como salida)
La función en la pregunta podría acortarse a
check_if_variable_is_set () { [ -n "${!1+x}" ]; }
o incluso:
check_if_variable_is_set () { [ -v "$1" ]; }
o incluso:
check_if_variable_is_set()[[ -v $1 ]]
Dónde -v
es una bash
prueba en un nombre de variable que será verdadera si la variable nombrada está establecida, y falsa en caso contrario.
POSIXY, podría escribirse:
check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }
Tenga en cuenta que todas esas son vulnerabilidades potenciales de inyección de comandos si el argumento de esa función podría terminar bajo el control de un atacante. Prueba por ejemplo con check_if_variable_is_set 'a[$(id>&2)]'
.
Para protegerse de eso, es posible que desee verificar primero que el argumento sea un nombre de variable válido. Para variables:
check_if_variable_is_set() {
case $1 in
("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
(*) eval '[ -n "${'"$1"'+x}" ]'
esac
}
(tenga en cuenta que [[:alpha:]]
buscará caracteres alfabéticos en su localidad mientras que algunos shells solo aceptan caracteres alfabéticos del conjunto de caracteres portátil en su variable)