Co oznacza podstawienie $ {! Var_name + x}?


Odpowiedzi:


17

W bashpowłoce ${!var}jest zmienna pośrednia. Rozwija się do wartości zmiennej, której nazwa jest przechowywana $var.

Rozszerzenie zmiennej ${var+value}jest rozszerzeniem POSIX, które rozwija się, valuejeśli zmienna varjest ustawiona (bez względu na to, czy jej wartość jest pusta, czy nie).

Łącząc je, ${!var+x}rozwinie się do, xjeśli ustawiona jest zmienna, której nazwa jest przechowywana $var.

Przykład:

$ 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}}"

(pusty wiersz jako wynik)


Funkcja w pytaniu może zostać skrócona

check_if_variable_is_set () { [ -n "${!1+x}" ]; }

lub nawet:

check_if_variable_is_set () { [ -v "$1" ]; }

lub nawet:

check_if_variable_is_set()[[ -v $1 ]]

Gdzie -vjest bashtest na nazwę zmiennej, która będzie prawdziwa, jeśli zmienna nazwana jest ustawiona, a false w przeciwnym razie.


POSIXly może być napisany:

check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }

Zauważ, że wszystkie te są potencjalne podatności na wstrzykiwanie poleceń, jeśli argumentem tej funkcji może być kontrola nad atakującym. Spróbuj na przykład z check_if_variable_is_set 'a[$(id>&2)]'.

Aby temu zapobiec, możesz najpierw sprawdzić, czy argument jest poprawną nazwą zmiennej. Dla zmiennych:

check_if_variable_is_set() {
  case $1 in
    ("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
    (*)  eval '[ -n "${'"$1"'+x}" ]'
  esac
}

(zwróć uwagę, że [[:alpha:]]sprawdzi znaki alfabetu w twoim języku, podczas gdy niektóre powłoki akceptują tylko znaki alfabetu z przenośnego zestawu znaków w swojej zmiennej)


Na ziemi nie ma nic bardziej kompletnego niż to. Zasługujesz na to za plik cookie.
Karim Manaouil,

@KarimManaouil Trzeci plik cookie trafia jednak do Stéphane'a :-)
Kusalananda
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.