Learn How to Properly Run Subshells Using Bash Scripts

How to Instruct Subshells to Run in Parallel in the Background

typing on computer
public domain

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, you create a subshell using the parenthesis notation:


#!/bin/bash
echo "Before starting subshell"
(
 count=1
 while [ $count -le 99 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
)
echo "Finished"

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 rest of the script. However, if you want to run subshells in parallel, you run them in the background, which is accomplished with the ampersand character  following the subshell expression, as shown here:


#!/bin/bash
echo "Before starting subshell"
(
 count=1
 while [ $count -le 99 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
) &
echo "Finished"

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. The next example has two subprocesses. The first one counts from 1 to 99, and the second one from 1000 to 1099.


#!/bin/bash
echo "Before starting subshell"
(
 count=1
 while [ $count -le 99 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
) &
(
 count=1000
 while [ $count -le 1099 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
) &
echo "Finished"

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


#!/bin/bash
echo "Before starting subshell"
(
 count=1
 while [ $count -le 99 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
) &
(
 count=1000
 while [ $count -le 1099 ]
 do
 echo "$count"
 sleep 1
 (( count++ ))
 done
) &
wait
echo "Finished"

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 can be used in function definitions so that they can be executed multiple times with different parameters.

Was this page helpful?