Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Linux

LINUX: Sub-shells

0.00/5 (No votes)
18 Aug 2010CPOL2 min read 10.5K  
Sub-shells in Linux


I mentioned sub-shells before and the way the affect aliases, but I did not talk much about the use of sub-shells themselves. A sub-shell can be quite useful in scripting, either to isolate certain environments, or to run sets of commands in parallel.

Using them is simple: Encapsulate the commands you want in a sub-shell within parentheses.

Bash
#!/bin/bash

( echo "Start sub-shell"
export ENVVAR="This is my sub-shell variable" )

echo $ENVVAR

The first thing you will notice when running this script is that the environment variable we set within the sub-shell does not propagate back to the script. The echo of $ENVVAR will be blank. Sub-shells are unidirectional; they use one-way passing of the environment, so it can inherit your current environment, but will not give back anything. This is very useful if you need to do multiple things that all require separate environments.

Bash
#!/bin/bash

( echo "Start sub-shell 1"
echo $ENVVAR
export ENVVAR="1"
echo $ENVVAR )

( echo "Start sub-shell 2"
echo $ENVVAR
export ENVVAR="2"
echo $ENVVAR )

( echo "Start sub-shell 3"
echo $ENVVAR
export ENVVAR="3"
echo $ENVVAR )

From the output, you will see that the ENVVAR set in one sub-shell does not carry over to the other. Each environment is isolated. This technique can be used if you are doing multiple code builds in parallel, each with their own development environment, variables, compilers, etc. As it stands, the above executes each sub-shell serially, running one then the next. How about running in parallel? Add an ampersand "&" at the end of each sub-shell to indicate backgrounding the whole block.

Bash
#!/bin/bash

( echo "Start sub-shell 1"
echo $ENVVAR
sleep 2
export ENVVAR="1"
echo $ENVVAR ) &

( echo "Start sub-shell 2"
echo $ENVVAR
sleep 2
export ENVVAR="2"
echo $ENVVAR ) &

( echo "Start sub-shell 3"
echo $ENVVAR
sleep 2
export ENVVAR="3"
echo $ENVVAR ) &

I put sleep 2 in each block to slow it down so you can see the effects of backgrounding. What you will see is that it will execute all the echo commands to print "Start..." at the same time, then waits 2 seconds, then the numbers get printed later. The three sub-shells are running in parallel! Did you catch the problem in the above though? You were returned to the prompt prior to the script finishing. You received your prompt and then all of a sudden, the numbers got printed out after. In order to tell the script to wait till all the sub-shells are finished before exiting the script, simply type "wait" at the end of the script. The final script will look like:

Bash
#!/bin/bash

( echo "Start sub-shell 1"
echo $ENVVAR
export ENVVAR="1"
echo $ENVVAR ) &

( echo "Start sub-shell 2"
echo $ENVVAR
sleep 2
export ENVVAR="2"
echo $ENVVAR ) &

( echo "Start sub-shell 3"
echo $ENVVAR
sleep 2
export ENVVAR="3"
echo $ENVVAR ) &

wait

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)