Nella bash
shell, ${!var}
è una indiretta variabile. Si espande al valore della variabile di cui viene mantenuto il nome $var
.
L'espansione della variabile ${var+value}
è un'espansione POSIX che si espande a value
se la variabile var
è impostata (indipendentemente dal fatto che il suo valore sia vuoto o meno).
Combinando questi, ${!var+x}
si espanderebbe x
se la variabile il cui nome è mantenuto $var
è impostata.
Esempio:
$ 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}}"
(riga vuota come output)
La funzione nella domanda potrebbe essere abbreviata in
check_if_variable_is_set () { [ -n "${!1+x}" ]; }
o anche:
check_if_variable_is_set () { [ -v "$1" ]; }
o anche:
check_if_variable_is_set()[[ -v $1 ]]
Dov'è -v
un bash
test su un nome di variabile che sarà vero se la variabile nominata è impostata, e falso altrimenti.
POSIXly, potrebbe essere scritto:
check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }
Si noti che tutte queste sono potenziali vulnerabilità nell'iniezione di comandi se l'argomento di tale funzione potrebbe finire per essere sotto il controllo di un utente malintenzionato. Prova ad esempio con check_if_variable_is_set 'a[$(id>&2)]'
.
Per evitare ciò, è possibile verificare prima che l'argomento sia un nome di variabile valido. Per le variabili:
check_if_variable_is_set() {
case $1 in
("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
(*) eval '[ -n "${'"$1"'+x}" ]'
esac
}
(nota che [[:alpha:]]
controllerà i caratteri alfabetici nelle tue impostazioni locali mentre alcune shell accettano solo i caratteri alfabetici dal set di caratteri portatile nella loro variabile)