当管道后面跟着命令分组时到底发生了什么?

当管道后面跟着命令分组时到底发生了什么?

我看到这样的表达式command1 | {command2;command3;command4},我在想这实际上意味着什么,我知道管道符号,我知道{...}强制运行主 shell 中大括号内的命令,但我很困惑它们的组合含义。

答案1

管道的各个部分有多复杂并不重要,如果需要,您通常可以将它们可视化为单独的脚本(特别是在像这样bash无论如何都会在子 shell 中运行管道的每个部分的 shell 中)。

剧本

command2
command3
command4

... 哪个大致{ command2; command3; command4; }翻译成的(不考虑{ ...; }名义上意味着命令不在子shell中运行),是从执行中给出的输入

command1

根据第一个脚本中的这三个命令正在执行的操作,其中一个或多个命令可能会消耗来自 的输入command1,并且如果其中一个或多个命令产生任何输出,则该输出将进入管道的下一部分,或者终端或管道输出重定向到的任何地方。

答案2

{...}强制运行主 shell 中大括号内的命令

这并不能很好地描述大括号的一般作用。以不创建子 shell 的方式将命令括起来。换句话说,大括号本身并不创建子 shell:大括号中的代码在同一个 shell 中执行,就好像没有大括号一样,而不是括号中的代码始终在子 shell 中执行(因此它的重定向、变量、等等不影响父 shell 或任何其他 shell)。

大括号的目的是允许在语法需要单个命令的情况下编写复杂的命令。例如,在command1 | { command2; command3; command4; }(请注意空格和最后的分号是必需的)中,管道的右侧是{ command2; command3; command4; }。该命令{ command2; command3; command4; }执行command2,然后command3,然后command4。所有这些命令都从管道获取输入。 (由于命令连续运行,command3因此获取运行后留下的任何输入command2,依此类推。)

答案3

将大括号视为未命名的函数。例如

command234 () { command2; command3; command4; }

command1 | command234 

给出相同的结果。当事情变得太复杂时,我更喜欢命名分组。如果只是为了测试。

答案4

标准输出command1将用于命令块中的第一个命令,该命令开始从标准输入读取。在大多数情况下,这将是command2

相关内容