gpt4 book ai didi

Bash 命令组 : Why do curly braces require a semicolon?

转载 作者:行者123 更新时间:2023-11-29 08:46:15 27 4
gpt4 key购买 nike

我知道当 grouping commands in bash 时圆括号 () 和花括号 {} 之间的目的区别.

但为什么花括号结构在最后一个命令后需要一个分号,而对于圆括号结构,分号是可选的?

$ while false; do ( echo "Hello"; echo "Goodbye"; ); done$ while false; do ( echo "Hello"; echo "Goodbye" ); done$ while false; do { echo "Hello"; echo "Goodbye"; }; done$ while false; do { echo "Hello"; echo "Goodbye" }; donebash: syntax error near unexpected token `done'$ 

我正在寻找一些关于为什么会出现这种情况的见解。我不是在寻找诸如“因为文档是这样说的”“因为它是那样设计的” 这样的答案。我想知道为什么它是这样设计的。或者它是否只是一件历史文物?

这至少可以在以下版本的 中观察到:

  • GNU bash,版本 3.00.15(1)-release (x86_64-redhat-linux-gnu)
  • GNU bash,版本 3.2.48(1)-release (x86_64-apple-darwin12)
  • GNU bash,版本 4.2.25(1)-release (x86_64-pc-linux-gnu)

最佳答案

因为 {} 只有当它们是命令中的第一个单词时才会被识别为特殊语法。


这里有两个重要的点,都可以在definitions section中找到。 bash 手册。首先是元字符列表:

metacharacter

A character that, when unquoted, separates words. A metacharacter is a blank or one of the following characters: ‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’.

该列表包括圆括号但不包括大括号(既不是花括号也不是方括号)。请注意,它不是对 shell 具有特殊含义的字符的完整列表,而是分隔标记的字符的完整列表。所以 {} 不会分隔标记,只有当它们与元字符(例如空格或分号)相邻时才会被视为标记本身。

虽然大括号不是元字符,但它们在 parameter expansion 中被 shell 特殊对待。 (例如 ${foo})和 brace expansion (例如 foo.{c,h})。除此之外,他们只是普通的角色。例如,将文件命名为 {ab}}{ 是没有问题的,因为这些词不符合任一参数扩展的语法(这需要${ 之前)或大括号扩展(这需要在 {} 之间至少有一个逗号)。就此而言,您可以使用 {} 作为文件名,而无需引用符号。同样,您可以调用文件 ifdonetime,而无需考虑引用名称。

后面这些标记是“保留字”:

reserved word

A word that has a special meaning to the shell. Most reserved words introduce shell flow control constructs, such as for and while.

bash 手册不包含完整的保留字列表,这很不幸,但它们肯定包括 Posix 指定的:

!    {    }
case do done elif else
esac fi for if in
then until while

以及 bash(和其他一些 shell)实现的扩展:

[[   ]]
function select time

这些词与内置词(如[)不同,因为它们实际上是shell语法的一部分。内置函数可以作为函数或 shell 脚本实现,但保留字不能,因为它们会改变 shell 解析命令行的方式。

保留字有一个非常重要的特性,bash 手册中实际上没有突出显示,但在 Posix 中非常明确。 (除时间外,上述保留字列表均取自于此):

This recognition [as a reserved word] shall only occur when none of the characters is quoted and when the word is used as:

  • The first word of a command …

(识别保留字的地方的完整列表略长,但以上是一个很好的总结。)换句话说,保留字只有在命令的第一个字。而且,由于 {} 是保留字,如果它们是命令中的第一个单词,它们只是特殊语法。

例子:

ls }  # } is not a reserved word. It is an argument to `ls`
ls;} # } is a reserved word; `ls` has no arguments

关于 shell 解析,尤其是 bash 解析,我还有很多可以写的,但它们很快就会变得乏味。 (例如,关于何时 # 开始注释以及何时它只是一个普通字符的规则。)大概的总结是:“不要在家里尝试这个”;实际上,唯一可以解析 shell 命令的是 shell。并且不要试图理解它:它只是任意选择和历史异常的随机集合,其中许多但并非全部基于不使用新功能破坏古老的 shell 脚本的需要。

关于Bash 命令组 : Why do curly braces require a semicolon?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21246552/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com