加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash命令组:为什么花括号需要分号?

发布时间:2020-12-16 01:36:25 所属栏目:安全 来源:网络整理
导读:当知道 grouping commands in bash时,我知道括号()和大括号{}之间目的的区别. 但是为什么大括号结构在最后一个命令之后需要分号,而对于括号构造,分号是可选的? $while false; do ( echo "Hello"; echo "Goodbye"; ); done$while false; do ( echo "Hello";
当知道 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" }; done
bash: syntax error near unexpected token `done'
$

我正在寻找一些洞察力,为什么会这样.我不是在寻找答案,如“因为文档说的这样”或“因为它是这样设计的”.我想知道为什么它是这样设计的.或者也许如果它只是一个历史文物?

至少可以在以下版本的bash中看到:

> 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)

因为{和}只有在命令中的第一个单词才被识别为特殊语法.

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

metacharacter

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

该列表包括圆括号,但不包括括号(既不是卷曲也不是正方形).请注意,它不是shell的特殊意义的完整的字符列表,但它是分隔标记的字符的完整列表.所以{和}不要分开标记,只有当它们与元字符(如空格或分号)相邻时才会被认为是令牌.

虽然大括号不是元字符,但它们在parameter expansion(例如${foo})和brace expansion(例如,foo.{c,h})中由shell特别处理.除此之外,它们只是普通人物.命名文件{ab}不存在任何问题,例如或{},因为这些单词不符合任一参数扩展的语法(需要在{}之前的$或扩展)(这需要至少一个{和}之间的逗号).对于这一点,您可以使用{或}作为文件名,而无需引用符号.同样,您可以调用文件,如果,完成或时间,而不必考虑引用名称.

这些后缀是“保留字”:

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脚本的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读