自动加载在 zsh 中有什么作用?

What does autoload do in zsh?

我找不到 zsh 中广泛使用的 autoload 命令的文档。谁能用通俗易懂的英语解释一下?

更具体一点:自动加载模块是什么意思,例如在这一行中:

autoload -Uz vcs_info

它有什么作用?


我已经尝试 autoload --helpman autoload,谷歌搜索 - 没有成功。谢谢!

autoload 功能在 bash 中不可用,但在 ksh (korn shell) 和 zsh 中可用。在 zsh 上见 man zshbuiltins

函数的调用方式与任何其他命令相同。程序和函数之间可能存在名称冲突。 autoload 所做的是将该名称标记为函数而不是外部程序。该函数必须单独存在于一个文件中,文件名与函数名相同。

autoload -Uz vcs_info

-U 表示将函数 vcs_info 标记为自动加载并抑制别名扩展。 -z 表示使用 zsh(而不是 ksh)样式。另请参阅 functions 命令。

编辑(来自@ijoseph 建议的评论):

所以它记录了名称是函数而不是外部程序的事实 - 它不会调用它,除非使用 -X 选项,它只会影响调用时的搜索路径。如果函数名称不与程序名称冲突,则不需要。在你的函数前加上 f_ 之类的前缀,你可能永远不需要它。

有关详细信息,请参阅 http://zsh.sourceforge.net/Doc/Release/Functions.html

autoload 告诉 zsh 在 $FPATH/$fpath 中查找包含 function definition[= 的文件58=],而不是 $PATH/$path 中包含 可执行文件 脚本或二进制文件的文件。

脚本

脚本只是在脚本 运行 时执行的一系列命令。例如,假设您有一个名为 hello 的文件,如下所示:

echo "Setting 'greeting'"
greeting='Hello'

如果该文件是可执行文件并且位于您 $PATH 的目录之一中,那么您可以 运行 只需键入其名称即可将其作为脚本。但是脚本有自己的 shell 进程副本,因此它们所做的任何事情都不会影响调用 shell 的环境。上面对 greeting 的赋值只会在脚本中生效;脚本退出后,它不会对您的交互式 shell 会话产生任何影响:

$ hello
Setting 'greeting'
$ echo $greeting

$ 

函数

一个函数被定义一次并保留在shell的内存中;当您调用它时,它会在当前 shell 内执行,因此可能会产生副作用:

hello() {
  echo "Setting 'greeting'"
  greeting='Hello'
}

$ hello
Setting 'greeting'
$ echo $greeting
Hello

因此,当您想要修改 shell 环境时,您可以使用函数。 Zsh 行编辑器 (ZLE) 也使用函数 - 当您将键绑定到某个动作时,该动作被定义为 shell 函数(必须添加到 ZLE使用 zle -N 命令)。

现在,如果您有很多函数,那么您可能不希望每次开始新的 shell 时都在 .zshrc 中定义所有函数;这会减慢 shell 启动速度,并使用内存来存储您可能不会在 shell 生命周期内调用的函数。因此,您可以将函数定义放入它们自己的文件中,以它们定义的函数命名,然后将文件放入 $FPATH 中的目录中,其工作方式类似于 $PATH.
Zsh 已经在默认 $FPATH 中附带了一堆标准函数。但除非您首先告诉它该命令是一个函数,否则它不会知道在那里寻找命令。

这就是 autoload 的作用:它说“嘿,Zsh,这里的命令名称是一个函数,所以当我尝试 运行 它时, 在我的 FPATH 中查找它的定义,而不是在我的 PATH 中查找可执行文件。"

第一次 运行 一个 autoloaded 函数时,Zsh 获取定义文件。然后,如果文件中除了函数定义之外没有任何内容, 如果设置了 shell 选项 KSH_AUTOLOAD,它将继续使用您的参数调用函数供应。但是,如果未设置该选项并且文件包含函数定义之外的任何代码(如函数使用的变量的初始化),则不会自动调用该函数。在这种情况下,您可以在定义文件后调用文件中的函数,以便第一次调用能够正常工作。