Переменные окружения, содержащие функции, являются взломом bash. У Zsh нет ничего похожего. Вы можете сделать что-то подобное с несколькими строками кода. Переменные окружения содержат строки; более старые версии bash, до обнаружения Shellshock , хранили код функции в переменной, имя которой совпадает с именем функции, а за значением () {
следует код функции, после которого следует }
. Вы можете использовать следующий код, чтобы импортировать переменные с этой кодировкой и попытаться запустить их с настройками, подобными bash. Обратите внимание, что zsh не может эмулировать все функции bash, все, что вы можете сделать, это немного приблизиться (например, чтобы $foo
разделить значение и расширить подстановочные знаки, а также сделать массивы на основе 0).
bash_function_preamble='
emulate -LR ksh
'
for name in ${(k)parameters}; do
[[ "-$parameters[name]-" = *-export-* ]] || continue
[[ ${(P)name} = '() {'*'}' ]] || continue
((! $+builtins[$name])) || continue
functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done
(Как отметил Стефан Шазелас , первооткрыватель Shellshock, более ранняя версия этого ответа могла выполнить произвольный код на этом этапе, если определение функции было некорректно. это может быть функция, импортированная из среды.)
Версии bash после Shellshock кодируют функции в среде, используя недопустимые имена переменных (например BASH_FUNC_myfunc%%
). Это затрудняет их надежный анализ, поскольку zsh не предоставляет интерфейс для извлечения таких имен переменных из среды.
Я не рекомендую делать это. Полагаться на экспортируемые функции в скриптах - плохая идея: это создает невидимую зависимость в вашем скрипте. Если вы когда-либо запускаете свой сценарий в среде, в которой нет вашей функции (на другом компьютере, в задании cron, после изменения файлов инициализации оболочки…), ваш сценарий больше не будет работать. Вместо этого сохраните все свои функции в одном или нескольких отдельных файлах (что-то вроде ~/lib/shell/foo.sh
) и запустите свои сценарии, импортировав функции, которые он использует ( . ~/lib/shell/foo.sh
). Таким образом, если вы измените foo.sh
, вы можете легко найти, какие сценарии полагаются на него. Если вы скопируете скрипт, вы легко сможете узнать, какие вспомогательные файлы ему нужны.
Zsh (и ksh перед ним) делает это более удобным, предоставляя способ автоматической загрузки функций в сценарии, где они используются. Ограничением является то, что вы можете поместить только одну функцию в файл. Объявите функцию как автозагрузку и поместите определение функции в файл, именем которого является имя функции. Поместите этот файл в каталог, указанный в $fpath
(который вы можете настроить через FPATH
переменную окружения). В вашем скрипте объявите автозагрузку функций с помощью autoload -U foo
.
Кроме того, zsh может компилировать скрипты, чтобы сэкономить время на анализ. Звоните, zcompile
чтобы скомпилировать скрипт. Это создает файл с .zwc
расширением. Если этот файл присутствует, то autoload
загрузит скомпилированный файл вместо исходного кода. Вы можете использовать zrecompile
функцию для (пере) компиляции всех определений функций в каталоге.