Learn How to Properly Run Subshells Using Bash Scripts

How to instruct subshells to run in parallel in the background

Graphic image of computer code with bands of blue and purple color

Negative Space / Pexels / CC0

A shell is a basic interface for entering commands on a Linux system. With it, you can enter a command directly or specify a file (script) that contains a sequence of commands to be executed. Shells are organized in a hierarchy, and any shell can create a new shell. The new shell is considered a child process—a subshell—of the parent shell that creates it.

By default, a subshell is dependent on its parent in the sense that if the parent process terminates, the subshell also terminates. Any output is passed from the subshell to the parent shell.

How to Create a Subshell

In a Bash shell script, create a subshell using the parenthesis notation:

#!/bin/bash
# subshell-example.sh with endless loop
(
while [ 1 ]
do
echo "Subshell running . . ."
done
)

In the example, the while loop is enclosed in parenthesis, which causes it to be executed in a subshell of the shell in which the script file is executed.

Running a Subshell in the Background

Unless you specify that the subshell is to be executed in the background, the parent shell waits for the subshell to finish before continuing with the rest of the script. However, to run subshells in parallel, run them in the background, which is accomplished with the ampersand character following the subshell expression, as shown here:

#!/bin/bash 
for ip in {1..254}; do
host=192.168.1.$ip
(ping -c 1 $host > /dev/null
if [ "$?" = 0 ]
then
echo $host
fi) &
done

Running Multiple Subshells in Parallel

If you create multiple subshells as background processes, you can run tasks in parallel. Typically, the operating system uses different processors or cores for each process and subprocess, assuming there are at least as many processors or cores as there are processes. Otherwise, tasks are assigned to the same processors or cores. In that case, the processor or core continuously switches between the assigned tasks until the tasks are completed.

Use the wait statement to tell the parent process to wait for the subprocesses to finish before proceeding with the rest of the script:

Uses for Subshells

Subshells are useful when commands need to be executed in a particular environment or directory. If each command is executed in a different subshell, there is no risk that variable settings will be mixed up. On completion, the settings and the current directory don't need to be restored, as the environment of the parent process is not affected by any of its subprocesses.

Subshells work with function definitions, executable many times with different parameters.