Bash 手册说
{ list; }
将命令列表放在大括号之间会导致该列表在当前 shell 上下文中执行。没有创建子shell。列表后面需要分号(或换行符)。
大括号是保留字,因此必须用空格或其他 shell 元字符将它们与列表分隔开。
括号是运算符,即使它们没有通过空格与列表分隔,也会被 shell 识别为单独的标记。
如果我删除分号,如下所示:
$ { date }
>
为什么它需要标准输入?
元字符是分隔单词的字符。分号和空格都是“shell 元字符”。为什么不能用空格分隔单词
date
and}
?为什么我们需要分号而不是空格来分隔单词?
答案1
正在等待收盘
}
。您已经输入了一个包含一个命令date }
和一个换行符的列表,因此您仍在命令组内,并且可以向列表中添加另一个命令或终止它。因此,它不是在等待标准输入(确切地说),而是在等待您完成在第一行开始的命令。如果您
}
在此处输入,您(可能)会从该命令中收到一条错误消息date
,指出它不理解“}
”。{
和}
是常见命令的有效参数,如第 1 点所示。例如,find
用作{}
参数。具体来说,只有“
{
”和“}
”是保留字。 shell 中的保留字仅当它们完全作为自己的整个单词给出时才有意义,并且仅在特别需要它们的地方。他们期望的最重要的地方是开始的一个命令。分号或换行符表示出
}
现在列表中下一个命令的开头,可以将其识别为保留字并给予特殊处理。这由 POSIX 为 shell 语法指定:此规则还意味着保留字不会被识别,除非在输入中的某些位置,例如在 a
<newline>
或<semicolon>
;之后。语法假定如果保留字是有意的,则它由用户正确定界如果另一个保留词“then”不能用作普通词,那会很烦人,所以这基本上是有意义的。相比之下,
(
and)
是运算符,可以出现在任何地方,如果它们用于其文字值,则需要转义。这本质上是一个历史文物,如果重来一次,也许会在一个方向或另一个方向上做出更一致的选择,或者可能会要求使用更复杂的解析器。
尤其是对于 Bash,命令分组的括号也需要与大括号扩展,并且解析器假设您不太可能对以空格开头的命令进行大括号扩展。
可以选择是否保持极端情况的历史兼容性,并且其他一些 shell(例如 zsh)具有更聪明的解析器,并且能够处理{ date }
您想要的含义。
答案2
它正在等待您完成命令。如果您编写不完整的 if 或 while 或其他,也会发生同样的情况:
$ if date >
该命令在手册中定义得很清楚:A
{ list; }
是复合命令:复合命令
{ 列表; } 列表必须以换行符或分号终止。
那里明确指出:“以换行符或分号终止”