命令列表和 } 之间的分隔符

命令列表和 } 之间的分隔符

Bash 手册说

{ list; } 

将命令列表放在大括号之间会导致该列表在当前 shell 上下文中执行。没有创建子shell。列表后面需要分号(或换行符)。

大括号是保留字,因此必须用空格或其他 shell 元字符将它们与列表分隔开。

括号是运算符,即使它们没有通过空格与列表分隔,也会被 shell 识别为单独的标记。

如果我删除分号,如下所示:

$ { date }
>
  1. 为什么它需要标准输入?

  2. 元字符是分隔单词的字符。分号和空格都是“shell 元字符”。为什么不能用空格分隔单词dateand }?为什么我们需要分号而不是空格来分隔单词?

答案1

  1. 正在等待收盘}。您已经输入了一个包含一个命令date }和一个换行符的列表,因此您仍在命令组内,并且可以向列表中添加另一个命令或终止它。

    因此,它不是在等待标准输入(确切地说),而是在等待您完成在第一行开始的命令。如果您}在此处输入,您(可能)会从该命令中收到一条错误消息date,指出它不理解“ }”。

  2. {}是常见命令的有效参数,如第 1 点所示。例如,find用作{}参数。

    具体来说,只有“ {”和“ }”是保留字。 shell 中的保留字仅当它们完全作为自己的整个单词给出时才有意义,并且仅在特别需要它们的地方。他们期望的最重要的地方是开始的一个命令。

    分号或换行符表示出}现在列表中下一个命令的开头,可以将其识别为保留字并给予特殊处理。这由 POSIX 为 shell 语法指定:

    此规则还意味着保留字不会被识别,除非在输入中的某些位置,例如在 a<newline><semicolon>;之后。语法假定如果保留字是有意的,则它由用户正确定界

    如果另一个保留词“then”不能用作普通词,那会很烦人,所以这基本上是有意义的。相比之下, (and)是运算符,可以出现在任何地方,如果它们用于其文字值,则需要转义。这本质上是一个历史文物,如果重来一次,也许会在一个方向或另一个方向上做出更一致的选择,或者可能会要求使用更复杂的解析器。


尤其是对于 Bash,命令分组的括号也需要与大括号扩展,并且解析器假设您不太可能对以空格开头的命令进行大括号扩展。

可以选择是否保持极端情况的历史兼容性,并且其他一些 shell(例如 zsh)具有更聪明的解析器,并且能够处理{ date }您想要的含义。

答案2

  1. 它正在等待您完成命令。如果您编写不完整的 if 或 while 或其他,也会发生同样的情况:

    $ if date
    >
    
  2. 该命令在手册中定义得很清楚:A{ list; }是复合命令:

    复合命令

    { 列表; } 列表必须以换行符或分号终止。

    那里明确指出:“以换行符或分号终止”

相关内容