在zsh中等价$ {BASH_SOURCE [0]}?

Tha*_*tos 51 shell zsh

标题应该说明一切.我正在寻找与${BASH_SOURCE[0]}zsh 相当的东西.

注意:我一直在互联网上找到" $0等同于${BASH_SOURCE[0]}",但这似乎是错误的:$0似乎是执行命令的名称.(这是argv[0],这是有道理的.)在我的剧本呼应$ 0( .zshrc)给出zsh$0,这是不一样的东西${BASH_SOURCE[0]}是.事实上,除了内部文件之外,${BASH_SOURCE[0]}似乎可以工作.zsh.zshrc

我真正在做什么.zshrc(那是行不通的):

echo ${BASH_SOURCE[0]}
source `dirname $0`/common-shell-rc.sh
Run Code Online (Sandbox Code Playgroud)

源失败($0zsh),echo输出为空行.

编辑: 显然,为了$0工作,我需要选项FUNCTION_ARGZERO选项集.有没有办法测试是否在脚本中设置了这个?(所以我可以暂时设置它)除非你设置nofunction_argzero,它显然是打开的,它在我的shell中.仍然无济于事$0.(我想b/c我不是一个功能.)

Hui*_*eng 41

${BASH_SOURCE[0]}在zsh中的等价物是${(%):-%N},NOT $0(如OP所说,后者在.zshrc中失败)

这里%表示对值的快速扩展, %N表示"zsh当前正在执行的脚本,源文件或shell函数的名称,

以最近开始的为准.如果没有,这相当于参数$ 0."(来自man zshmisc)

  • 很好 - 这应该适用于OP,但请注意,真正的`$ BASH_SOURCE`等价物是'%x`,而不是'%N`,因为它引用封闭的_file_,即使在_functions_内部调用 - 换句话说:use `$ {(%): - %X}` (12认同)
  • 如果您想要一种更简洁的方式来查找包含源代码的目录的绝对路径,这将处理:`${${(%):-%x}:A:h}` (5认同)

mkl*_*nt0 31

${(%):-%x}是最接近zsh相当于bash$BASH_SOURCE(和ksh${.sh.file}) - 没有 $0.

向郑铮提供的帽子提示,在他的回答中提供了关键的指针和背景信息.

它返回封闭脚本的(可能是相对的)路径,

  • 无论脚本是否来源.
    • 具体来说,它也适用于初始化/配置文件文件,例如~/.zshrc(不像$0,莫名其妙地返回shell的路径).
  • 无论是否从脚本中定义的函数内部调用(不像$0,它返回函数内的函数名).

以唯一的区别$BASH_SOURCE我发现在以下晦涩的场景-这甚至有可能(在zsh中5.0.5观察)中的错误:在一个函数内嵌套另一个函数内部在执行的脚本,${(%):-%x}没有返回时封闭脚本路径该嵌套函数被调用(再次),已采购(收益存在或是"的zsh").


背景资料${(%):-%x}:

  • (%):-代替参数(变量)中的变量名称expand(${...})使转义序列可用,通常用于表示提示字符串中的环境信息,例如在PS1变量中用于确定显示为主要交互式提示的字符串.

    • %是参数扩展标志的一个实例,所有这些都列在man zshexpn标题下Parameter Expansion Flags.
  • %x是可以在提示字符串中使用的转义序列之一,它的功能如上所述; 还有更多,比如%d代表当前的目录.

    • man zshmisc列出标题下的所有可用序列SIMPLE PROMPT ESCAPES.


dol*_*s3m 12

如果你想让你的脚本同时兼容 bash 和 zsh,你可以使用${BASH_SOURCE[0]:-${(%):-%x}}. 结果值将取BASH_SOURCE[0]它的定义时,并且${(%):-%x}}BASH_SOURCE[0]没有定义。


Gil*_*il' 11

$0是正确的.在源脚本中,这是脚本的名称,因为它被传递给.source内置(因此,如果path_dirs设置了该选项,则可能需要执行$path查找以查找脚本的实际位置).

.zshrc不是来源,这解释了为什么$0没有设置.zshrc.无论如何,你知道文件名和位置:它是${ZDOTDIR-~}/.zshrc.

  • 只是为了澄清和强调......在**`zsh`**(以及可能的其他shell)中,`$ 0`的值是源脚本而不是调用脚本.这不是它在Bash中的工作方式.因此,zsh中的`$ 0`与Bash中的`$ {BASH_SOURCE [0]}`相同. (2认同)
  • @toxalot:“zsh”中的“$0”相当于“大多数但不是全部”情况下的“$BASH_SOURCE”;例外情况是:(a) 在_初始化/配置文件_(例如,`~/.zshrc`)中,`$0` 莫名其妙地报告了 *shell 的* 路径,以及 (b) 在_function_ 内部,它报告了_function's_ 名称。同样,真正的等价物是“${(%):-%x}”。 (2认同)

Fra*_*ter 10

如果您在dotfiles目录中符号链接到.zshrc并想要引用目录中的其他文件,请尝试以下操作:

SOURCE=${(%):-%N}
while [ -h "$SOURCE" ]; do
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DOTFILES_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
Run Code Online (Sandbox Code Playgroud)

(我从这里得到了循环脚本.)