Shell Scripting – Subshell vs Subprocess

How a sub-shell differs from a sub-process/child-process can often be a cause for confusion. Hopefully, this article may help alleviate it.

A shell is just a program that interprets the commands entered into it and executes them. These commands are either built into the shell program or they are external programs which are invoked by the shell.

Built-in commands are those commands that are contained within the shell. They are part of the shell program. Depending on the shell, these built-in commands may vary. Here is a list of bash’s built in commands. type is a command that can used to find out if a command is a built-in or not.
Capture

A sub-process is created by the parent shell by making the system calls fork followed by exec. A sub-process executes independently of the parent process. Every command that is not a built-in command is just a script that is executed as a child-process by the parent shell. A child-process gets a copy of all of the environment variables of the parent shell. Environment variables are those variables that are declared with the export keyword. Please note that it is also possible to source a script into the parent shell. A sourced script is executed within the parent shell. No sub-process is created for it.

A sub-shell is a sub-process that is an almost identical copy of the parent shell. They get a copy of not just the environment variables but also the non-exported shell variables, functions etc. There are several ways to create a sub-shell. For example, any command within (…) is executed in a sub-shell. Each command in a pipeline is also executed in a sub-shell.

#!/bin/bash
name1="test1"
export name2="test2"
{ typeset name3="test3"} #This is a local variable. It cannot be accessed outside the braces.
(echo $name1) #This is executed in a sub-shell. Hence prints 'name1'
(echo $name2) #This is executed in a sub-shell. Hence prints 'name2'
(echo $name3) #This is executed in a sub=shell. It does not have access to the local variable 'name3'
./script2.sh #script2.sh is executed as a sub-process. Can only print 'name2'
. script2.sh #script2.sh is sourced into the current script. Can print name1, name2
source script2.sh #script2.sh is sourced into the current script. Can print name1, name2
view raw script1.sh hosted with ❤ by GitHub

#!/bin/bash
echo $name1
echo $name2
echo $name3
view raw script2.sh hosted with ❤ by GitHub

There are shells that may optimize out the creation of a sub-shell. ksh93 exhibits this behavior.

 

6 thoughts on “Shell Scripting – Subshell vs Subprocess

Add yours

  1. “Please note that it is also possible to source a script into the parent shell. A sourced script is executed within the parent shell. No sub-process is created for it.”
    What if there’s an external program in this script?

    Like

  2. * BASH_SUBSHELL indicates the subshell level
    * SHLVL indicates the subprocess level

    “`
    $ echo “$BASH_SUBSHELL – $SHLVL”
    0 – 1
    $ ( echo “$BASH_SUBSHELL – $SHLVL” )
    1 – 1
    $ ( ( echo “$BASH_SUBSHELL – $SHLVL” ) )
    2 – 1
    $ ( ( ( echo “$BASH_SUBSHELL – $SHLVL” ) ) )
    3 – 1
    $ bash
    $ echo “$BASH_SUBSHELL – $SHLVL”
    0 – 2
    $ ( echo “$BASH_SUBSHELL – $SHLVL” )
    1 – 2
    “`

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at WordPress.com

Up ↑

%d bloggers like this: