ixt*_*lix 34 zsh shell-script function
所以我开始使用zsh. 我喜欢就好。它看起来非常酷和光滑,并且当前工作目录和实际命令行在不同的行上这一事实很好,但与此同时,我注意到它zsh可能比 慢一点bash,尤其是在将文本打印到屏幕。
我最喜欢的一点是它zsh与我在.bashrc.
一个抱怨虽然。这些功能都完美运行,但我无法弄清楚导出系统是如何工作的。
我.bashrc导出了其中一些函数,以便我可以在其他地方使用它们,例如在脚本和外部程序中使用export -f.
在 zsh 中,似乎甚至没有谈论导出。是自动加载吗?这两件事是一样的吗?我很难弄清楚这一点。
Gil*_*il' 17
包含函数的环境变量是 bash hack。Zsh 没有类似的东西。你可以用几行代码做类似的事情。环境变量包含字符串;在Shellshock被发现之前,较旧版本的 bash将函数代码存储在一个变量中,该变量的名称是函数的名称,其值() {后跟函数代码,后跟}. 您可以使用以下代码导入具有此编码的变量,并尝试使用类似 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
Run Code Online (Sandbox Code Playgroud)
(正如Shellshock的最初发现者Stéphane Chazelas所指出的,如果函数定义格式错误,这个答案的早期版本可以在此时执行任意代码。这个版本不会,但当然一旦你执行任何命令,它可能是从环境中导入的函数。)
后 Shellshock 版本的 bash 使用无效变量名(例如BASH_FUNC_myfunc%%)对环境中的函数进行编码。这使得它们更难可靠地解析,因为 zsh 不提供从环境中提取此类变量名称的接口。
我不建议这样做。依赖脚本中的导出函数是一个坏主意:它会在您的脚本中创建一个不可见的依赖项。如果你曾经在没有你的函数的环境中运行你的脚本(在另一台机器上,在一个 cron 作业中,在更改你的 shell 初始化文件之后,......),你的脚本将不再工作。相反,将所有函数存储在一个或多个单独的文件(类似于~/lib/shell/foo.sh)中,并通过导入它使用的函数来启动脚本 ( . ~/lib/shell/foo.sh)。这样,如果您修改foo.sh,您可以轻松搜索依赖于它的脚本。如果你复制一个脚本,你可以很容易地找出它需要哪些辅助文件。
Zsh(以及之前的 ksh)通过提供一种在使用它们的脚本中自动加载函数的方法使这更方便。限制是每个文件只能放置一个函数。将函数声明为自动加载,并将函数定义放在名称为函数名称的文件中。将此文件放在 中列出的目录中$fpath(您可以通过FPATH环境变量进行配置)。在您的脚本中,使用autoload -U foo.
此外 zsh 可以编译脚本,以节省解析时间。调用zcompile以编译脚本。这将创建一个带有.zwc扩展名的文件。如果此文件存在,autoload则将加载已编译的文件而不是源代码。您可以使用该zrecompile函数来(重新)编译目录中的所有函数定义。