Bash命令组:为什么花括号需要分号? [英] Bash command groups: Why do curly braces require a semicolon?

查看:153
本文介绍了Bash命令组:为什么花括号需要分号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道()和花括号 {} 在目的上的区别https://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html#Command-Grouping rel = nofollow noreferrer>在bash中分组命令。

I know the difference in purpose between parentheses () and curly braces {} when grouping commands in bash.

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

But why does the curly brace construct require a semicolon after the last command, whereas for the parentheses construct, the semicolon is optional?


$ 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" }; done
bash: syntax error near unexpected token `done'
$ 

为什么会这样。我不是在寻找诸如之类的答案,因为文档中是这样因为它是按这种方式设计的 。我想知道 为什么 是这种方式设计的。也许只是历史遗物?

I'm looking for some insight as to why this is the case. I'm not looking for answers such as "because the documentation says so" or "because it was designed that way". I'd like to know why it was designed this is way. Or maybe if it is just a historical artifact?

至少在以下版本的


  • GNU bash版本3.00.15(1)-发行版(x86_64-redhat-linux-gnu)

  • GNU bash版本3.2.48(1)-发行版(x86_64-apple-darwin12)

  • GNU bash,版本4.2.25(1)-发行版(x86_64-pc-linux-gnu)

推荐答案

因为 {} 仅被视为特殊

这里有两个要点,这两个要点都在bash手册的定义部分。首先,是元字符的列表:

There are two important points here, both of which are found in the definitions section of the bash manual. First, is the list of metacharacters:


元字符



一个字符,当不加引号时,将单词分开。元字符是空格或以下字符之一:'|','&',';','(',')','<'或'>'。

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



该列表包括括号,但不包括括号(既不卷曲也不正方形)。请注意,这不是具有特殊含义的字符的完整列表,而是分隔标记的字符的完整列表。因此 {} 不会分隔标记,只有与元字符相邻的标记才会被视为标记本身,

That list includes parentheses but not braces (neither curly nor square). Note that it is not a complete list of characters with special meaning to the shell, but it is a complete list of characters which separate tokens. So { and } do not separate tokens, and will only be considered tokens themselves if they are adjacent to a metacharacter, such as a space or a semi-colon.

尽管括号不是元字符,但是它们在参数扩展(例如 $ {foo} )和< a href = http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion>括号扩展(例如 foo。{c,h } )。除此之外,它们只是普通字符。例如,命名文件 {ab} } {没问题,因为这些词不会符合参数扩展(在 {之前需要 $ )或大括号扩展(要求在 {} 之间至少一个逗号)。为此,您可以使用 {} 作为文件名,而不必引用符号。同样,您可以调用文件,如果完成时间

Although braces are not metacharacters, they are treated specially by the shell in parameter expansion (eg. ${foo}) and brace expansion (eg. foo.{c,h}). Other than that, they are just normal characters. There is no problem with naming a file {ab}, for example, or }{, since those words do not conform to the syntax of either parameter expansion (which requires a $ before the {) or brace expansion (which requires at least one comma between { and }). For that matter, you could use { or } as a filename without ever having to quote the symbols. Similarly, you can call a file if, done or time without having to think about quoting the name.

后面的这些标记是保留字:

These latter tokens are "reserved words":


保留字



对外壳具有特殊含义的单词。大部分保留字介绍了外壳流控制构造,例如 for while



bash手册没有包含保留字的完整列表,这很不幸,但是它们当然包括Posix指定的内容:

The bash manual doesn't contain a complete list of reserved words, which is unfortunate, but they certainly include the Posix-designated:

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

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

as well as the extensions implemented by bash (and some other shells):

[[   ]]
function  select time

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

These words are not the same as built-ins (such as [), because they are actually part of the shell syntax. The built-ins could be implemented as functions or shell scripts, but reserved words cannot because they change the way that the shell parses the command line.

有一个非常重要的保留字的功能,在bash手册中并未实际突出显示,但在 Posix (从中提取了以上保留字列表,但时间除外):

There is one very important feature of reserved words, which is not actually highlighted in the bash manual but is made very explicit in Posix (from which the above lists of reserved words were taken, except for time):


[保留字]仅在不引用任何字符且该词用作以下内容时才会出现:

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


  • 命令的第一个单词…

(保留位置的完整列表可以识别的单词稍长一些,但是上面的内容是一个很好的总结。)换句话说,保留的单词仅当它们是ac的第一个单词时才保留指令。而且,由于 {} 是保留字,因此如果它们是命令中的第一个字,则它们只是特殊的语法。

(The full list of places where reserved words is recognized is slightly longer, but the above is a pretty good summary.) In other words, reserved words are only reserved when they are the first word of a command. And, since { and } are reserved words, they are only special syntax if they are the first word in 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脚本的需求。


There is lots more I could write about shell parsing, and bash parsing in particular, but it would rapidly get tedious. (For example, the rule about when # starts a comment and when it is just an ordinary character.) The approximate summary is: "don't try this at home"; really, the only thing which can parse shell commands is a shell. And don't try to make sense of it: it's just a random collection of arbitrary choices and historical anomalies, many but not all based on the need to not break ancient shell scripts with new features.

这篇关于Bash命令组:为什么花括号需要分号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆