我的bash版本4.4.19的man页面上写着:
管道
管道是由一个或多个命令序列组成的,这些命令之间用控制操作符|或|&分隔。 管道的格式为:
[time [-p]] [ ! ] command [ [|||&] command2 ... ]
没错,这很有道理。然后,在该部分的后面:
在管道中的每个命令都作为单独的进程(即在子shell中)执行。
这也是合理的,并且很容易证明:
当然,仅在子shell中运行单个命令 - 在
管道
管道是由一个或多个命令序列组成的,这些命令之间用控制操作符|或|&分隔。 管道的格式为:
[time [-p]] [ ! ] command [ [|||&] command2 ... ]
没错,这很有道理。然后,在该部分的后面:
在管道中的每个命令都作为单独的进程(即在子shell中)执行。
这也是合理的,并且很容易证明:
$ pwd
/Users/ravron
$ ls | grep src # yes, src _does_ exist
src
$ cd src | true # cd in subshell has no effect on parent session
$ pwd
/Users/ravron
然而,我注意到上面的管道定义是这样表述的,即甚至一个简单的命令也可以是一个管道。毕竟,在语法中,除了command
以外的所有内容都是可选的:
[time [-p]] [ ! ] command [ [|||&] command2 ... ]
当然,仅在子shell中运行单个命令 - 在
man bash
术语中称为“简单命令” - 显然是无用的。例如,cd
不起作用,变量设置也不起作用等等。但是,实际情况是,尽管简单命令与(相当退化的)管道的语法匹配,但它们并没有在子shell中执行,这与man页面相矛盾。以下是我的理解列表:
- 管道的语法意味着简单命令也是管道。
- man页面说管道中的命令在子shell中运行。
- 简单命令不在子shell中运行。
man bash
中一个不太重要的 bug?
execve()
通常要求在“单独的实用程序环境”中发生的要求。 - Charles Duffy