在 zsh 中,path
是一个特殊的数组变量,其内容链接到众所周知的PATH
变量。
如此特别,事实上,定义和调用函数
f() { local -r path=42 }
导致错误f: read-only variable: path
。如果局部变量被声明为可变的(即没有-r
),一切都按预期工作。我无法用其他变量名重现此错误。
为什么会发生此错误,是故意的吗?其他名称是否存在类似规则?
我在 macOS 10.12.6 上使用 zsh 5.2 (x86_64-apple-darwin16.0)。
TL;DR 不要重用“特殊内置参数”,例如
path
因为它们很特殊。或者根据邮件列表可以使用-h
标志:(但是,更改
path
为整数可能会弄乱忘记此覆盖并假设path
是的后续代码path
......)接下来是更长的挖掘时间(但我完全错过了
-h
隐藏的东西......)这是特殊变量的属性(特性?错误?),但不是用户链接的类似变量:
还有各种其他参数表现出这种行为:
所以有些变量就像动物农场中的一样,比其他变量更特别。此错误消息来自各个地方
Src/params.c
,如果修改为打印哪个消息是我们在编译时zsh
找到的特定消息:是相当通用的代码
这表明问题发生在其他地方;非特殊变量无疑没有
PM_READONLY
设置,而失败的特殊变量则设置。下一个显而易见的地方是local
具有各种名称(typeset
export
...)的代码。这些都是内置的,所以可以发现潜伏在Src/builtin.c
这些都
bin_typeset
设置了各种标志,所以让我们研究该功能的来源......在评论中发誓,检查。请注意,事情很复杂,请检查。没有什么真正跳出来,虽然兔子洞(因为当“将参数视为模式”-m
选项未设置时,这里就是这种情况)似乎导致typeset_single
函数......有一些
POSIXBUILTINS
与 相关的代码readonly
,但在我的测试外壳中已关闭所以我将忽略该代码(我希望。这可能是一个修格斯巢穴而不仅仅是兔子洞吗?)。同时!一些调试指向通过以下行
PM_READONLY
打开的标志path
这又来自输入函数
on
时已经打开的变量typeset_single
,叹息,所以回到bin_typeset
我们去......好吧,基本上有一个默认情况下TYPESET_OPTSTR
通过某些宏启用的变量;PM_READONLY
相反,当用户提供的变量通过此代码路径运行时,它PM_READONLY
会被关闭并且一切都很好。这是否可以更改以便可以将特殊变量(例如
path
可以将其设为只读)对于 ZSH 开发人员来说是一个问题(试试 zsh-workers 邮件列表?),否则同时不要乱用特殊变量。