You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:46:17