ravron
ravron

Reputation: 11211

Why aren't single-command pipelines executed in subshells?

My bash man page for version 4.4.19 says:

Pipelines

A pipeline is a sequence of one or more commands separated by one of the control operators | or |&. The format for a pipeline is:

[time [-p]] [ ! ] command [ [|||&] command2 ... ]

Sure. That makes sense. Then, later in that section:

Each command in a pipeline is executed as a separate process (i.e., in a subshell).

Also reasonable, and easily proved:

$ 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

However, I noticed that the definition of a pipeline, above, is worded such that even a simple command is a pipeline. After all, in the syntax, everything except command is optional:

[time [-p]] [ ! ] command [ [|||&] command2 ... ]

Now, of course, running even single commands — in man bash terminology, "simple commands" — in subshells would be really quite useless. cd wouldn't work, variable setting wouldn't work, etc. However, the reality — that simple commands, despite matching the syntax for a (rather degenerate) pipeline, are not executed in subshells — appears to be at odds with the man page. In list form, here's my understanding:

What am I missing, or is this an admittedly inconsequential bug in man bash?

Upvotes: 3

Views: 143

Answers (2)

chepner
chepner

Reputation: 530872

The manual is just imprecise. The POSIX spec (section 2.12) is more explicit (bold face added by me):

Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

bash, by default, takes the position of implementing each of those subshells as a subprocess. (The lastpipe option introduced in bash 4.2 lets the final command execute in the current shell environment/process.)

The shell's grammar says that a pipeline can consist of one or more commands, but the shell's semantics distinguish between pipelines of one command and pipelines of two or more commands.

Upvotes: 3

Barmar
Barmar

Reputation: 780688

The manual never defines the word "subshell". While you might intuitively assume that a subshell is always a subprocess of the original shell, the degenerate case of a single command uses the original shell process as the subshell.

Some other shells go further, always running the last command in a pipeline in the original shell.

Upvotes: 1

Related Questions