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

Tim*_*Tim 3 bash

Bash 手册说

{ list; } 
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

$ { date }
>
Run Code Online (Sandbox Code Playgroud)
  1. 为什么它需要 stdin 输入?

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

Mic*_*mer 5

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

    所以它不是在等待标准输入(确切地说),而是在等待你完成你在第一行开始的命令。如果你}在这里输入,你(可能)会从date命令中得到一个错误,说它不理解“ }”。

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

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

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

    该规则还暗示,除了在输入中的某些位置(例如 a<newline><semicolon>;之后)之外,不会识别保留字。语法假定如果保留字是有意的,则由用户正确分隔

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


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

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