Was bedeutet die Substitution $ {! Var_name + x}?


Antworten:


17

In der bashShell ${!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, valuewenn die Variable festgelegt varist (unabhängig davon, ob ihr Wert leer ist oder nicht).

Wenn Sie diese kombinieren, wird ${!var+x}dies erweitert, xwenn die Variable festgelegt wird, in der der Name beibehalten $varwird.

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 -vist ein bashTest 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.)


Nichts auf der Erde ist vollständiger als dies. Sie verdienen einen Keks dafür.
Karim Manaouil

@ KarimManaouil Ein Drittel dieses Cookies geht jedoch an Stéphane :-)
Kusalananda
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.