Do functions run as subprocesses in Bash?

The Advanced Bash-Scripting Guide is not always reliable and its example scripts contain out-dated practices such as using the effectively deprecated backticks for command substitution, i.e., `command` rather than $(command).

In this particular case, it’s blatantly incorrect.

The section on Shell Functions in the (canonical) Bash manual definitively states that

Shell functions are executed in the current shell context; no new process is created to interpret them.


Curly brace functions will run within the calling shell process, unless they need their own subshell which is:

  • when you run them in the background with &
  • when you run them as a link in a pipeline

Redirections or extra env. variables won't force a new subshell:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

If you define the function with parentheses instead of curlies:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

it will always run in a new process.

Command substitution $() also always creates processes in bash (but not in ksh if you run builtins inside it).


The command in question from that example looks like:

echo ${arrayZ[@]/%e/$(replacement)}

The example later states:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

Being charitable to ABS Guide, what they apparently meant to write is that the function runs inside a command substitution and the command inside a command substitution runs in a subshell.