Ответ о расширении переменной ${+name}
в основном решает проблему.
Я просто хочу добавить немного информации о сравнении скорости, чтобы завершить тему. Причина, по которой используется команда стиля (($+commands[tree]))
, заключается в том, что поиск команд в массиве выполняется быстрее, чем command -v tree
, which -a tree
.
❯ export TIMEFMT=$'%U user %S system %P cpu %*E total'
❯ time (for i ({1..100}) if (($+commands[tree])); then echo 1 &>/dev/null; fi)
0.00s user 0.00s system 89% cpu 0.006 total
❯ time (for i ({1..100}) if command -v tree &>/dev/null; then echo 1 &>/dev/null; fi)
0.00s user 0.00s system 95% cpu 0.010 total
❯ time (for i ({1..100}) if which -a tree &>/dev/null; then echo 1 &>/dev/null; fi)
0.01s user 0.01s system 97% cpu 0.021 total
Похоже, вам нужна переменная, содержимое которой генерируется динамически.
bash
не поддерживает дисциплины ksh93 или динамический именованный каталог zsh или подстановку значений mksh , что упростило бы задачу, но вы могли бы используйте такой хак, используя namerefs:
var_generator() { date --iso-8601=ns; }
var_history=()
typeset -n var='var_history[
${##${var_history[${#var_history[@]}]=$(var_generator)}},${#var_history[@]}-1
]'
Здесь с var
, определенным как ссылка на элемент массива $var_history
, с использованием того факта, что индексы массива оцениваются динамически и позволяют запускать произвольный код (, здесь используется для запуска функции var_generator
и назначения его вывод в новый элемент массива ).
Тогда:
bash-5.1$ echo "$var"
2021-03-23T13:36:43,243211696+00:00
bash-5.1$ echo "$var"
2021-03-23T13:36:45,517726619+00:00
Это звучит слишком запутанно, хотя здесь можно просто использовать $(var_generator)
. Однако одно преимущество заключается в том, что вы все еще можете делать такие вещи, как ${var#pattern}
, в то время как bash
(, в отличие от zsh
), не позволит вам делать ${$(cmd)#pattern}
.