在 Bash 中,我注意到有一些选择某些内容作为运算符或保留字的示例:(所有引用均来自 Bash 手册)
(...)
和{...}
:它们都用于创建命令列表。但第一个是运算符,第二个是保留字:
除了创建子 shell 之外,由于历史原因,这两种结构之间还存在细微的差异。大括号是保留字,因此必须用空格或其他 shell 元字符将它们与列表分隔开。括号是运算符,即使它们没有通过空格与列表分隔,也会被 shell 识别为单独的标记。
!
: 表示逻辑否定。当它位于管道之前时,它是一个保留字:
如果保留字'!'在管道之前,退出状态是上述退出状态的逻辑非。
它是三个地方的运算符:
- 在 shell 算术表达式中,
- 在条件表达式中
[...]
- 在 内的条件表达式中
[[...]]
。
我的问题是:
为什么其中一些是保留字,而另一些是运算符,尽管它们具有相同的含义?
我的目的不是了解 Bash 的设计历史,或者为什么 Bash 是这样设计的(所以可以跳过这个问题),尽管这会有所帮助。我的目的是了解运算符可以做什么而保留字不能做什么,反之亦然(请参阅以下两个问题)。
将某物设为运算符而不是保留字有什么好处?
将某些内容设为保留字而不是运算符有什么好处?
还有其他类似的例子吗?
我的目的不仅仅是收集例子,而是从中得出一些原则(参见上面两个问题),以便我可以更好地理解具体细节,不再容易混淆和犯错误。所以跳过这个问题就好了。
答案1
首先,让我们区分“运算符”和“保留字”这两个东西。它们甚至不处于同一抽象层次,它们是完全不同的东西。从标准英语定义开始*:
操作员:表示操作的符号或函数。
(请注意,“符号”并不意味着“单个字符”;a单词也是一个符号。)
手术:根据形式规则(例如加法、乘法和微分规则)更改或操纵数字、数量、表达式等的过程。
希望清楚吗?自己编几个例子;我会帮你的。
然后我们有“保留字”,我们实际上只需要查找“保留”:
预订的:专为特定目的或个人保留
在这种情况下,我们指的是 shell 设计者为特定目的而保留的单词,并且不得用于其他目的(至少,不能在不转义它们的情况下)。
注意这些条款确实不是描述不相交的事物。 也就是说,有是保留字,表示根据正式规则对表达式(或命令)进行更改或操作。
事实上,!
作为管道之前的“保留字”是事实上操作员该管道的退出状态,仅根据标准英语定义。
这个问题纯粹是语义问题,并且差异并不像该特定手册的作者所认为的那么重要。这些标签的应用来了后设计事实和标签用于描述设计中嵌入的具体行为;两者都不物品(“保留字”或“运算符”)相对于其他具有固有的优势。这标签在某些情况下可能有优势,但坦率地说,它们实际上只是意味着不同的东西。 它们只是两个不同的术语。
具体程序意义:
从粗略看过去该特定手册,这个问题的关键术语实际上似乎是:
- 代币
- 单词
- 元字符
- 操作员
- 控制操作员
- 保留字
按照这个顺序。
我的收获:
单词是必须通过放置元字符与其他单词分开的东西。运算符本身由“单词分隔符”(元字符)组成,因此不需要专门与单词分开。
{...}
因此,和之间的全部重要区别(...)
可以在您引用的引文中传达出来,甚至无需使用引发此问题的术语。这里有一个改写:
除了创建子 shell 之外,由于历史原因,这两种结构之间还存在细微的差异。大括号必须用空格或其他 shell 元字符与列表分隔。括号被 shell 识别为单独的标记,即使它们没有通过空格与列表分隔。
全部意义就在那里。这定义“运算符”和“保留字”之间的区别。没有其他区别。
*定义取自新牛津美国词典。