У 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:]]
перевірятимуть алфавітні символи у вашій мові, тоді як деякі оболонки приймають лише алфавітні символи з набору переносних символів у їх змінній)