shell zsh中的${BASH_SOURCE[0]}等价物?

o3imoua4  于 2023-10-23  发布在  Shell
关注(0)|答案(7)|浏览(151)

标题应该说明一切。我在zsh中寻找一个与${BASH_SOURCE[0]}等价的代码。

  • 注意:* 我在网上不断发现“$0相当于${BASH_SOURCE[0]}“,但这似乎是假的:$0似乎是执行命令的名称。在我的脚本(.zshrc)中回显$0,得到zsh对应$0,这与${BASH_SOURCE[0]}不同。事实上,${BASH_SOURCE[0]}似乎可以在zsh中工作,除了内部的.zshrc文件。
  • 我在我的.zshrc中真正做的事情(不工作):*
echo ${BASH_SOURCE[0]}
source `dirname $0`/common-shell-rc.sh

源失败($0zsh),echo输出一个空行。

**编辑:**显然,为了让$0工作,我需要设置FUNCTION_ARGZERO选项。有什么方法可以测试这是否在脚本中设置?(这样我就可以暂时设置它)它显然是开着的,除非你设置nofunction_argzero,而且它在我的shell中是开着的。$0仍然没有得到任何东西。(我认为B/c我不在函数中。)

wgeznvg7

wgeznvg71#

zsh中的${BASH_SOURCE[0]}等价物是${(%):-%N},而不是$0(正如OP所说,后者在.zshrc中失败)
这里%表示对值的提示扩展,%N表示“zsh当前正在执行的脚本、源文件或shell函数的名称,
以最近开始的为准。如果没有,则等效于参数$0。"(来自man zshmisc

ttp71kqs

ttp71kqs2#

**${(%):-%x}**是最接近的zsh等价于bash$BASH_SOURCE(和ksh${.sh.file})- * 不是 * $0

感谢郑惠在his answer中提供了关键的指针和背景信息。
它返回封闭的 script 的(可能是相对的)路径,

  • 不管脚本是否被 * 源化 *。
  • 具体来说,它还可以在初始化/配置文件中工作,例如~/.zshrc(不像$0,它会莫名其妙地返回 shell 的路径)。
  • 无论是否从脚本中定义的 function 内部调用(不像$0,它返回函数内部的 function 名称)。

我发现的与$BASH_SOURCE的唯一区别是下面这个模糊的场景--这甚至可能是一个bug(在zsh 5.0.5中观察到的):在源脚本中的一个函数 * 嵌套在另一个函数 * 中,${(%):-%x}不会 * 返回嵌套的脚本路径,当该嵌套函数被调用时(再次)* 稍后 在 * 被源调用后(返回nothing或'zsh')。
${(%):-%x}背景信息

  • (%):-代替了参数(变量)扩展(${...})中的变量名,使转义序列可用,这些转义序列通常用于在 prompt 字符串中表示环境信息,例如在PS1变量中用于确定显示为主交互式提示的字符串。
  • %是一个参数扩展标志的示例,所有这些都在man zshexpn中的标题Parameter Expansion Flags下列出。
  • %x是可以在提示符字符串中使用的转义序列之一,它的功能如上所述;还有很多,例如%d表示当前目录。
  • man zshmisc在标题SIMPLE PROMPT ESCAPES下列出了所有可用的序列。
baubqpgj

baubqpgj3#

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

vm0i2vca

vm0i2vca4#

$0正确。在源脚本中,这是一个脚本的名称,因为它被传递到.source内置(因此,如果设置了path_dirs选项,您可能需要执行$path查找以查找脚本的实际位置)。
.zshrc没有源代码,这解释了为什么$0没有设置为.zshrc。您知道文件名和位置:是${ZDOTDIR-~}/.zshrc

q5lcpyga

q5lcpyga5#

如果你正在符号链接到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 )"

(我从here得到了循环脚本。)

u5rb5r59

u5rb5r596#

你可能在找$_

# foo.sh
source foo2.sh

# foo2.sh
echo $_

收益率

# ./foo.sh
foo2.sh
mm9b1k5b

mm9b1k5b7#

把这些放在一起,就可以在bash和zsh中工作了:

SCRIPT_FILE_REL_PATH="${BASH_SOURCE[0]}"
if [[ "$SCRIPT_FILE_REL_PATH" == "" ]]; then
  SCRIPT_FILE_REL_PATH="${(%):-%N}"
fi
SCRIPT_FILE_PATH="`realpath $SCRIPT_FILE_REL_PATH`"
SCRIPT_DIR="`dirname $SCRIPT_FILE_PATH`"

相关问题