In der bash
Shell ${!var}
befindet sich eine variable Indirektion. Es wird auf den Wert der Variablen erweitert, deren Name beibehalten wird $var
.
Die Variablenerweiterung ${var+value}
ist eine POSIX-Erweiterung , die erweitert wird, value
wenn die Variable festgelegt var
ist (unabhängig davon, ob ihr Wert leer ist oder nicht).
Wenn Sie diese kombinieren, wird ${!var+x}
dies erweitert, x
wenn die Variable festgelegt wird, in der der Name beibehalten $var
wird.
Beispiel:
$ 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}}"
(leere Zeile als Ausgabe)
Die Funktion in der Frage könnte auf verkürzt werden
check_if_variable_is_set () { [ -n "${!1+x}" ]; }
oder auch:
check_if_variable_is_set () { [ -v "$1" ]; }
oder auch:
check_if_variable_is_set()[[ -v $1 ]]
Wo -v
ist ein bash
Test für einen Variablennamen, der wahr ist, wenn die benannte Variable gesetzt ist, und andernfalls falsch.
POSIXly könnte geschrieben werden:
check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }
Beachten Sie, dass all dies potenzielle Sicherheitsanfälligkeiten hinsichtlich der Befehlsinjektion sind, wenn das Argument für diese Funktion möglicherweise von einem Angreifer kontrolliert wird. Versuchen Sie es zum Beispiel mit check_if_variable_is_set 'a[$(id>&2)]'
.
Um dies zu verhindern, sollten Sie zunächst überprüfen, ob das Argument ein gültiger Variablenname ist. Für Variablen:
check_if_variable_is_set() {
case $1 in
("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
(*) eval '[ -n "${'"$1"'+x}" ]'
esac
}
(Beachten Sie, dass in Ihrem Gebietsschema[[:alpha:]]
nach alphabetischen Zeichen gesucht wird, während einige Shells nur alphabetische Zeichen aus dem tragbaren Zeichensatz in ihrer Variablen akzeptieren.)