There are 2 main ways that I know of so far:
Explicitly: wrapping parentheses around a list of commands
Implicitly: every command in a pipeline
Are there more ways, either explicitly or implicitly, in which one creates subshells in bash?
There are 2 main ways that I know of so far:
Explicitly: wrapping parentheses around a list of commands
Implicitly: every command in a pipeline
Are there more ways, either explicitly or implicitly, in which one creates subshells in bash?
From man bash
:
&
, the shell
executes
the command in the background in a subshell. The shell does not wait
for the command to finish, and the return status is 0.coproc
reserved word.complete
command: when called with the -C command
option, command
is executed in a subshell environment, and
its output is used as the possible completions.It depends on what you mean by “subshell”. And you may be missing the point in your “every command in a pipeline” bullet.
Any time you run any (external) program
(i.e., a script or binary executable, in contrast to a shell builtin),
unless you use exec program
,
you run it in a sub-process (or processes).
The shell forks and executes the program.
ls | wc
does not create a subshell any more than ls
and wc
do alone.
The interesting thing is that including it in a pipeline can cause a shell builtin to run in a subshell. Consider this example:
$ read v cat # This is input typed by the user. $ echo "$v" cat $ echo cougar | read v $ echo "$v" cat
The second read v
command is run in a subshell
because it is part of the echo cougar | read v
pipeline.
Therefore, the value cougar
is lost, and $v
retains its first value.
Likewise, commands like
$ echo foo | cd /
$ cd / | cat
$ echo foo | exit
$ exit | cat
do not affect the main shell.