bash中的简单命令是否在子shell中运行,因为单个命令可以构成管道?

bash中的简单命令是否在子shell中运行,因为单个命令可以构成管道?,bash,Bash,Bash参考手册状态: 管道是一个或多个命令的序列 因此,任何命令都不会因此被限定为管道吗?这似乎不是一个纯粹的语义问题,因为手册还规定: 管道中的每个命令都在其自己的子shell中执行 因此,这意味着echo foo实际上可以在子shell中运行一样简单?是的,单个命令也是一个管道。要验证这一点,请运行任何commamd,比如echo foo,然后使用下面的命令打印PIPESTATUS变量 echo ${PIPESTATUS[0]} 是的,单个命令也是一个管道。要验证这一点,请运行任何com

Bash参考手册状态:

管道是一个或多个命令的序列

因此,任何命令都不会因此被限定为管道吗?这似乎不是一个纯粹的语义问题,因为手册还规定:

管道中的每个命令都在其自己的子shell中执行


因此,这意味着echo foo实际上可以在子shell中运行一样简单?

是的,单个命令也是一个管道。要验证这一点,请运行任何commamd,比如echo foo,然后使用下面的命令打印PIPESTATUS变量

echo ${PIPESTATUS[0]}

是的,单个命令也是一个管道。要验证这一点,请运行任何commamd,比如echo foo,然后使用下面的命令打印PIPESTATUS变量

echo ${PIPESTATUS[0]}
本手册不是正式规范。bash遵循的形式化规范实现了一个庞大的is超集。该规范更清楚地说明了规则,并添加了格式以强调:

此外,多命令管道的每个命令都位于子shell环境[…]

因此,简单的单一命令管道1实际上是管道;但是2不调用子shell。

该手册不是正式规范。bash遵循的形式化规范实现了一个庞大的is超集。该规范更清楚地说明了规则,并添加了格式以强调:

此外,多命令管道的每个命令都位于子shell环境[…]


因此,简单的单一命令管道1实际上是管道;但是2不会调用子shell。

反向工作,您的上一条语句是正确的,即在bash提示符上运行单个命令会导致fork。因此,从这个意义上讲,单个命令被视为管道

但是bash-c的“echo hello”不会导致额外的fork

与bash-c“echo hello | wc”等适当的管道相比,单个命令被视为一种特殊情况,它创建2个分叉,每个分叉1个用于处理echo和wc,而原始进程则等待这些子进程完成


尽管我不得不说,像echo这样简单的东西实际上是一个内部命令,这意味着它完全在bash可执行文件中实现,并且子程序永远不会执行。

反向工作,您的最后一句话是正确的,即在bash提示符上运行单个命令会导致fork。因此,从这个意义上讲,单个命令被视为管道

但是bash-c的“echo hello”不会导致额外的fork

与bash-c“echo hello | wc”等适当的管道相比,单个命令被视为一种特殊情况,它创建2个分叉,每个分叉1个用于处理echo和wc,而原始进程则等待这些子进程完成


尽管我不得不说,像echo这样简单的东西实际上是一个内部命令,这意味着它完全在bash可执行文件中实现,并且子程序永远不会执行。

echo'Yes'| echo$echo'Yes'| echo$as echo hello | wc仍然会分叉一个子shell来运行echo hello,因此,我不确定内置与外部的区别是否与此相关。我认为OP根本没有询问是否存在预执行fork,而不是为管道组件创建子shell的fork。@CharlesDuffy但子shell只是fork还是比它更重要?公平地说,没有太多的内容了,而且“子shell”这个短语有点过头了。由于echo hello | wc仍然会分叉一个子shell来运行echo hello,所以我不确定内置与外部的区别是否与此相关。我认为OP根本没有询问是否存在预执行fork,而不是为管道组件创建子shell的fork。@CharlesDuffy但子shell只是fork还是比它更重要?公平地说,没有更多的问题了,这个短语有点过分了。我不相信OP问的是次shell级别,而是关于是否发生了分叉。set-x确实可以用来验证这一点,但您需要先执行类似PS4=':$BASHPID+;如果BASHPID与父进程相同,那么该行就没有fork。我不相信OP询问的是子shell级别,而是询问是否发生fork。set-x确实可以用来验证这一点,但您需要先执行类似PS4=':$BASHPID+;如果BASHPID与父进程的相同,则该行没有fork。