4

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?

5

From man bash:

  • If a command is terminated by the control operator &, 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.
  • A coprocess is a shell command preceded by the coproc reserved word.
    A coprocess is executed asynchronously in a subshell, as if the command had been terminated with the & control operator
  • Shell builtin 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.
  • Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment
  • Can you clarify the 3rd bulletpoint? I don't understand it. Also, I was thinking of answering my own question with a complete and clearly formatted list based on everyone's responses (including my original points). But it seems you've come very close to doing that, and I'll gladly accept your answer if you'd like to do that. – Nadim Hussami Apr 13 '17 at 19:43
  • @NadimHussami my fault, see edit – resc Apr 13 '17 at 20:15
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.