bash - 在 Bash 中,每一段 "${BASH_SOURCE:-${(%):-%x}}" 是什么意思
问题描述
最近我想知道在 Bash 中获取当前正在运行的脚本/文件的路径的最佳方法。
我找到了很多答案。特别是:
"${BASH_SOURCE:-${(%):-%x}}"
我记得当时决定这是满足我需求的最佳解决方案。现在我试图记住为什么。我知道一些片段是什么意思,但不是全部。即使有我所知道的,我也无法把它们放在一起来理解它。有用。但为什么?
我在网络上的任何地方(包括搜索它的一部分)所做的一切努力都失败了,所以我找不到我最初找到它的地方。
谁能告诉我每件作品的含义(甚至可能建议我为什么选择这个而不是其他答案)?
谢谢!
第二天更新:@rici 的精彩回答(和评论)解释了一切,包括我为什么选择它。
看来我选择了整个表达式是为了使我使用它的源文件能够在 bash 和 zsh 中可靠地使用——这是一个目标。使用双重替换,整个表达式在任一 shell 中都得到相同的答案。
解释了为什么我对 bash 中的 ${(%):-%x} 部分没有任何意义(或通过谷歌找到任何有意义的东西),因为......嗯......它在 bash 中没有多大意义,大声笑,因为它是用于 zsh 的。出于这个原因,我现在为此添加了一个 zsh 标签。
一个小时后的第二次更新,以防这对任何人都有帮助:我现在已经找到了这个:
${BASH_SOURCE[0]} 在 zsh 中的等价物?
...这是我${(%):-%x}
最初得到的地方,最值得注意的是这个具体的答案:
解决方案
这个特殊的表达式试图在 bash 和 zsh 中提供相同的结果:当前运行脚本的文件路径。
在 bash 中,
"${BASH_SOURCE:-${(%):-%x}}"
意思是“$BASH_SOURCE
如果它存在并且不为空,否则${(%):-%x}
”。只要您在$BASH_SOURCE
定义为非空值的上下文中使用它,否则${(%):-%x}
将永远不会使用无效的替换,并且 bash 不会抱怨它。[注1]
有关详细说明,$BASH_SOURCE
请参阅@mklement0 的出色回答。
现在,在 zsh 中,变量$BASH_SOURCE
通常没有定义(尽管我想它可能是从父级导出的),所以替换确实发生了,然后 zsh 用扩展替换它${(%):-%x}
。Bash 用户可能会发现它更加神秘,但我们可以将其分解如下:
${...:-...}
与 bash 中的含义相同:如果左手部分为空或未定义,则使用右手部分。与 bash 不同,zsh 允许左侧部分完全为空,而不仅仅是值为空的变量。{:-foo}
复杂的书写方式也是如此foo
。${(flags)...}
导致在扩展上评估指定的标志。在这种情况下,我们有 flag%
,这意味着应该对参数扩展进行“提示扩展”。[笔记2]如果没有处理标志,我们就剩下
{:-%x}
; 如第 1 点所示,这相当于 string%x
。但是该(%)
标志会触发%x
. 而在zsh提示扩展中,%x
是--等待它--当前正在执行的脚本文件的名字。
简而言之,在 zsh 中,${(%):-%x}
意味着(几乎)与 bash 中的完全相同$BASH_SOURCE
。因此,${BASH_SOURCE:-${(%):-%x}}
扩展为 bash 和 zsh 中的当前脚本源文件。
笔记
$BASH_SOURCE
另一方面,如果未定义或为空,则会产生“错误替换”。正如我们稍后将看到的,${(flags)...}
它是一种 zsh 特定的语法,但这并不是 bash 抱怨它的原因。bash,它看起来像一个%
不存在的参数的后缀删除(运算符)$(
。它抱怨,因为$(
它不是一个有效的参数名称。为了比较,考虑非常相似但有效的替换
${#%):-%x}
。与 具有相同的值$#
,因为$#
不以 . 结尾):-%x
。这种解析可能对人眼来说是令人惊讶的,但 bash 认为它是平淡无奇的。Zsh 与 bash 一样,具有高度可定制的提示,在提示变量之一中使用特殊的转义序列。(Posix 标准提示变量是
$PS1
,$PS2
和$PS4
;bash 和 zsh 都提供了其他几个变量。)Bash 提供了一些特殊的反斜杠序列(\u
例如,是当前用户名),并且还允许在扩展提示时解释任意参数扩展。Zsh 也有多种转义序列,但%
用作转义字符(%n
是当前用户名),如果prompt_subst
设置了 shell 选项,则允许参数扩展。请注意,您通常不能像在 bash 中那样
zsh
通过简单的设置来试验提示$PS1
,因为大多数zsh
安装都使用“提示主题”。启用提示主题后,您需要创建自己的主题以更改提示字符串,因为主题设置会在每个命令之前自动应用。
推荐阅读
- node.js - 使用文件夹导入模块并将数据传递给nodejs中的模块
- c - 索引怎么可能是字符串(i[s])?
- amazon-s3 - Oozie 在 EMR 上将操作数据路径从 S3 更改为 hdfs
- axios - Nuxt:在 .ENV 中设置 Axios BaseURL 不起作用?
- python - 预算午餐和晚餐的 Web Scraping Tabelog
- python - 映射 Django url 和视图
- artificial-intelligence - PDDL AI 规划中的一个错误
- entity-framework-core - 包含在实体框架中的问题
- python - Python Kivy:动态分配小部件ID的问题
- angular - 滚动加载时滚动中的角度材质虚拟滚动默认偏移量