zsh:“source”命令不会重新加载函数

zsh:“source”命令不会重新加载函数

(这是在带有 zsh 5.7.1 的 MacOS 上)

以下是我在 zsh 中加载自定义函数的方法:

# Custom functions
fpath=($HOME/.zfunc $fpath)
autoload -Uz mackupbackup
autoload -Uz tac
autoload -Uz airplane
autoload -Uz wakeMyDesktop

每个函数在~/.zfunc目录中都是它自己的文件。请注意,由于 . 此目录已符号链接到不同的目录mackup

我编写了一个新函数来将当前提交哈希复制到剪贴板。我在 $fpath 中创建了一个名为 的文件ghash,编写了该函数,autoload在 my 中添加了一个新行.zshrc并执行了source ~/.zshrc

这是函数

# copy the commit hash of the given git reference, or HEAD if none is given
ref=$1

if [[ $ref ]]; then
  git rev-parse $1 | pbcopy
else
  git rev-parse HEAD | pbcopy
fi

采购之后.zshrc,该功能变得可用并且有效,但我想添加一行来打印其有效的确认:

echo "Copied $(pbpaste) to clipboard"

所以我添加了该行,保存了文件,然后.zshrc再次获取。

我再次运行该函数,但其​​行为没有改变!

我以为我做错了什么,所以我不断地更改功能和采购,.zshrc但没有效果。总而言之,我重新获取了.zshrc22 次资源,此时该操作需要 37 秒才能完成......

然后我意识到也许它没有重新加载该函数,所以我运行zsh启动一个新的实例(大约需要 1 秒),然后该函数开始按预期工作!

有人知道为什么source我选择了新功能,但功能更改后却没有更新吗?

source ~/.zshrc额外问题:为什么每次运行它都要花费更长的时间?

答案1

在实践中,获取 rc 文件很少(如果有的话),因为人们很少将它们编写为幂等的。一个典型的例子是您自己的情况,您每次都在路径前面添加相同的目录fpath,这当然意味着每次搜索该路径都需要更长的时间。而且,毫无疑问,这并不是您做此类事情的唯一地方。

您也没有正确理解自动加载。正如文档所述,没有主体的函数会自动加载函数第一次执行时。显然,如果函数已经加载,因此具有函数体,则它不会再次加载。

在再次调用该 函数之前,您需要先调用unfunction该函数。autoload

.zshrcZ shell 源中的示例包含一个freload()函数,该函数对所有以其参数命名的函数执行此操作。typeset -U path cdpath fpath manpath注意,它也确实如此。

答案2

虽然在 zsh 中将autoloada 标记name为在第一次引用时自动加载,但如果已经定义了该名称,它不会重新定义任何具有相同名称的现有函数,因为该名称在定义后就已被引用。为了实现您想要的,您必须在.zshrc再次采购之前先取消定义函数,或者为了更简化,创建一个用于自动加载的包装函数以检查给定的任何函数名称是否已定义,如果是,则在标记它们之前取消定义它们再次自动加载。

至于为什么.zshrc每次尝试后采购速度都会变慢,这是无法回答的.zshrc

相关内容