Що означає заміна $ {! Var_name + x}?


10

Я знайшов сценарій, який має функцію, яка перевіряє, чи встановлена ​​змінна, але я її не дуже добре розумію.

check_if_variable_is_set() {
    var_name=$1
    if [ -z "${!var_name+x}" ]; then
        false
    else
        true
    fi
}

Що саме відбувається з цією заміною?


пов'язані $ {! FOO} та zsh .
αғsnιη

Відповіді:


17

У bashоболонці ${!var}знаходиться змінна непрямість. Він розширюється до значення змінної, ім'я якої зберігається в $var.

Розширення змінної ${var+value}- це розширення POSIX, яке розгортається, valueякщо вказана змінна var(незалежно від того, чи її значення порожнє чи ні).

Поєднавши їх, ${!var+x}було б розширено, xякщо встановлена ​​змінна, ім'я якої зберігається $var.

Приклад:

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

(порожній рядок як вихід)


Функцію у питанні можна скоротити до

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

або навіть:

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

або навіть:

check_if_variable_is_set()[[ -v $1 ]]

Де -vце bashвипробування на ім'я змінної , яка буде вірно , якщо названа змінна встановлена, і брехня в іншому випадку.


POSIXly, можна було б написати:

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

Зауважте, що всі це потенційні вразливості введення команд, якщо аргумент цієї функції в підсумку може бути під контролем зловмисника. Спробуйте, наприклад, с check_if_variable_is_set 'a[$(id>&2)]'.

Щоб уберегтися від цього, ви можете спочатку переконатися, що аргумент - це дійсне ім'я змінної. Для змінних:

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

(зауважте, що [[:alpha:]]перевірятимуть алфавітні символи у вашій мові, тоді як деякі оболонки приймають лише алфавітні символи з набору переносних символів у їх змінній)


На землі немає нічого більш повного, ніж це. Ви заслуговуєте на це печиво.
Карим Манауїл

@KarimManaouil Третина цього файлу cookie йде до Stéphane, хоча :-)
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.