如何获取zsh中自动加载函数所在的目录?
问题
在.zshrc中配置了自动加载的函数fn1,想要动态获取它的位置,从而加载邻近文件夹中的函数fn2,但无论是在函数自动加载阶段还是运行阶段,尝试的路径写法都指向Shell当前目录,无法获取函数自身所在目录:
.zshrc配置:
fpath=(path/to/fn1 "$fpath[@]") autoload -U fn1
fn1文件内容:
# 以下三种写法解析后均为相对于Shell当前目录的路径 pathToFn2="${0:P:h}/../path/to/fn2" pathToFn2="${0:a:h}/../path/to/fn2" pathToFn2="$PWD/../path/to/fn2" fpath=($pathToFn2 "$fpath[@]") autoload -U fn2 function fn1() { # 或者在函数内部加载,但路径仍相对于Shell当前目录 pathToFn2="${0:P:h}/../path/to/fn2" pathToFn2="${0:a:h}/../path/to/fn2" pathToFn2="$PWD/../path/to/fn2" fpath=($pathToFn2 "$fpath[@]") autoload -U fn2 fn2 blarg } fn1 "$@"
请问如何在函数发现、加载或运行阶段获取当前函数文件的名称或所在目录?
解决方案
在zsh的自动加载机制中,$0在函数定义阶段指向当前Shell而非函数文件,要获取自动加载函数的文件路径,需借助zsh内置的functions命令结合函数名实现。
方法一:加载阶段获取路径
修改fn1文件,在定义函数前通过functions命令拿到函数文件的绝对路径:
# 获取fn1对应的文件路径 fn1_path=${functions[fn1]} # 提取文件所在目录 fn1_dir=${fn1_path:P:h} # 计算fn2所在目录的路径 pathToFn2="${fn1_dir}/../path/to/fn2" fpath=($pathToFn2 "$fpath[@]") autoload -U fn2 function fn1() { fn2 blarg } fn1 "$@"
方法二:运行阶段获取路径
如果需要在函数内部动态获取自身路径,可在函数体内执行functions命令:
function fn1() { # 在函数内部获取自身文件路径 fn1_path=${functions[fn1]} fn1_dir=${fn1_path:P:h} pathToFn2="${fn1_dir}/../path/to/fn2" fpath=($pathToFn2 "$fpath[@]") autoload -U fn2 fn2 blarg } fn1 "$@"
关键原理
functions[fn1]:当函数被标记为autoload时,该内置变量会存储函数对应的文件绝对路径${var:P:h}:zsh参数扩展语法,P用于将路径转换为绝对路径,h用于提取路径的目录部分(去除文件名)
内容的提问来源于stack exchange,提问作者xdhmoore
相关产品推荐
相关产品推荐

