我不明白为什么它们都需要,因为它们看起来zstyle
作用相同setopt
甚至更多?
答案1
setopt
设置 shell 选项
外壳选项是改变 shell 本身行为的布尔变量。setopt
打开或关闭它们。您可以setopt
不带参数运行来查看哪些 shell 选项已从其默认值切换。其中一些无法在运行时更改;相反,它们的作用是提供有关 shell 内部状态的信息。
可用的 shell 选项由 shell 决定;不可能创建自己的。但是,任何 shell 代码都可以决定读取 shell 选项的值并相应地更改其自身的行为。此外,shell 函数或可执行 shell 脚本(但不是source
d)可以在本地更改 shell 选项,而不影响其周围的 shell 的其余部分。
zstyle
提供命名空间属性
zstyle [<flag>] ( <namespace> | <selector> ) <property> <value>
是 Zsh 全局变量的替代品。它允许外壳代码(而不是 shell 本身)为用户提供一种配置设置以及存储其自身内部状态的方法,没有用实际的全局变量污染你的 shell。
与 shell 选项不同,zstyle
属性的修改不能在本地进行。相反,zstyle
使用命名空间和选择器系统。读取属性时zstyle
,您可以传递命名空间和要从中读取的属性的名称。然而,当环境一个zstyle
属性,你传递一个全局模式其功能类似于 CSS 选择器,让您可以同时为多个命名空间设置相同的属性。 (这种与 CSS 的相似性似乎是此处使用“样式”一词的原因。)
请注意,zstyle
并不关心您为名称空间使用什么语法。用作:
分层分隔符(如 Zsh 中所做的那样)完成系统)只是一个约定。
每个zstyle
属性都存储一个字符串数组。然而:
如果在设置属性时传递该
-e
标志,则在读取该属性时会将字符串评估为代码,从而可以创建计算属性– 这是全局变量不可能实现的。zstyle
提供几个获取和测试值的便捷方法,让您更轻松地将这些字符串数组转换为其他类型。
答案2
回顾历史会有所帮助。
zsh
首次发布于 1990 年。它吸收了 Bourne shell 和 csh 的优点。
Bourne shell 调整是通过单字母选项来完成的sh
,也可以使用set
特殊的内置选项进行调整。例如,以禁用通配符的方式sh -f
启动sh
,或者set -f
在运行时禁用通配符。
csh 使用您设置或取消设置的普通变量进行调整,其中一些变量映射到启动选项。例如,csh -x
以打印其正在执行的所有操作的模式启动 csh。或者您可以set verbose
在运行时进入该模式(unset verbose
以离开它)。
很多 zsh 都是基于 csh 的,因为 csh 是当时流行的 shell。在这里,它模仿了 csh,但认识到使用普通变量来存储选项设置是一个坏主意,它确实使用了不同的选项命名空间和单独的内置函数来设置/取消设置它们:setopt
和unsetopt
,并且这些选项被映射到单字母选项。
ksh
在 80 年代,给了一些 Bourne 选项的名称,这样你就可以用 来设置它们set -o optionName
(用 来取消设置set +o
)。
在 1991 年的 zsh 2.0.02 中,setopt
/unsetopt
被别名为set -o
/set +o
以与ksh
.
为了进行比较,bash
当时的选项是像 csh 中那样的普通变量,一些映射到启动/set
选项,而一些启动/set
选项并未全部映射到相应的变量。
set -o option
大约在 1990 年 1.06 到 1.08 之间的某个时刻被添加到 bash 中。
在 bash 2.0 (1996) 中,这些变量被删除并shopt
作为替换引入,因此您有两组选项,一些用set -o
/设置set +o
,一些用shopt -s
/设置shopt -u
。我不清楚为什么。
AFAIK,当它在 1992 年首次发布时set -o
,就已经在 POSIX.2 规范中了。sh
并且所有现代的类似 Bourne 的 shell 都支持设置选项,尽管除了 POSIX 指定的选项之外,每个 shell 的选项列表各不相同(并参见bash
上面提到的第二组选项),所以我倾向于使用set -o
而不是setopt
我自己。
zstyle
本身就是很久以后才添加的compstyle
1999 年,在一个可选模块中,作为早期以 zsh 函数形式编写的方法的 C 语言的概括和重新实现。它的主要用例过去是,现在仍然是允许对新的完成系统进行微调(尽管它可以并且已经用于其他事情)
它是一个独立于 shell 选项、变量或函数的命名空间。虽然 shell 选项或变量可以成为函数的本地选项,但zstyle
s AFAIK 始终是全局的,因此,如果只是为了这一点,选项或变量不能使用zstyle
s 重新实现,但这并不是说有多大价值。无论如何,为了向后兼容set -o
, /仍然setopt
必须保留。