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.