Understanding and Using Linux Subshells (Practical Guide)
A subshell is a child process launched by a shell, which is essentially a command-line interpreter.
It shares the properties of the parent shell but operates within a separate process space.
Subshells offer isolation and flexibility in executing commands and running scripts.
Subshells are commonly used in scripting for task automation, parallel execution, and modular coding, contributing to a more efficient and robust system.
- 1 Creating Subshells
- 2 Differences between a Shell and Subshell
- 3 Environment Variables and Subshells
- 4 Exit Status and Return Values
- 5 Job Control in Subshells
- 6 Command Execution in Subshells
- 7 Nested Subshells
- 8 Using Subshells in Scripts
- 9 Efficiency of Subshells vs. Native Shell Commands
- 10 Real-World Example (Automation with Subshells)
Creating Subshells
Using Parentheses
Subshells can be created using parentheses.
Command:
(echo "Inside subshell";)
This will create a subshell and print “Inside subshell.”
Starting a New Shell
You can invoke a new shell process by running a shell command such as bash
or sh
.
bash ls
Using pipeline (|
)
This depends on the specific shell you use.
In Bourne shell and KornShell (ksh), each part of the pipeline is executed in its own subshell.
This means that variable assignments or other changes to the shell environment made within one part of the pipeline will not affect the rest of the pipeline or the parent shell.
In the Bash shell, the rightmost command in the pipeline is usually executed in the current shell, while the others are executed in subshells.
This behavior can be altered in Bash by setting the lastpipe
shell option with the shopt
builtin.
Here’s an example to illustrate the difference:
echo "hello" | read var; echo $var
In Bash (without lastpipe
), this will print an empty line because the read
command is executed in a subshell, and the variable assignment doesn’t affect the parent shell.
In KornShell (with the sh
option), this will print “hello” because the read
command is executed in the current shell, and the variable assignment does affect the parent shell.
Differences between a Shell and Subshell
A shell is a command-line interpreter that processes user commands. A subshell, on the other hand, is a child process spawned by the shell. Here are the key distinctions:
- Shell: The main interface that interacts with the operating system’s kernel, managing user commands, scripting, and programs.
- Subshell: A separate instance of the shell, inheriting characteristics from its parent but running in its own process space. Any changes made inside a subshell will not affect the parent shell.
Command Example:
echo $BASHPID; (echo $BASHPID)
Output:
1633 1641
The output of the first echo
shows the parent shell’s process ID.
The output of the second echo
within parentheses indicates the subshell’s process ID, demonstrating that they are two different processes.
Environment Variables and Subshells
Environment variables are important in the context of subshells. Here’s how they interact:
Exporting Variables
Command:
export VAR="Outside"; (export VAR="Inside"; echo $VAR); echo $VAR
Output:
Inside Outside
The first print statement within the subshell shows the value “Inside,” while the second print statement in the parent shell shows the original value “Outside.”
Non-exported Variables
Command:
VAR="Outside"; (VAR="Inside"; echo $VAR); echo $VAR
Output:
Inside Outside
Again, the value is changed within the subshell but reverts back to the parent shell, as the variable is not exported, so the child does not inherit it.
Exit Status and Return Values
In Linux, commands return an exit status to indicate success or failure. Subshells also return exit statuses to their parent shells.
Command:
(echo "Inside subshell"; exit 3); echo $?
Output:
Inside subshell 3
This code creates a subshell that prints a string and then exits with status 3.
The parent shell prints the subshell’s exit status, demonstrating how it propagates from the subshell to the parent shell.
Job Control in Subshells
Subshells allow you to run tasks in the background, foreground, and monitor them efficiently.
Background Jobs
Command:
(echo "Starting"; sleep 5; echo "Done") &
Output:
[1] 1724 Starting Done
This sends the subshell process to the background. You will receive the process ID, and the job will continue to run.
Foreground Jobs
Command:
fg %1
This command brings job number 1 to the foreground if running in the background.
Monitoring Processes
Command:
jobs
Output:
[1]+ Running (echo "Starting"; sleep 5; echo "Done") &
This lists current background jobs.
Killing a Job
Command:
kill %1
This command terminates job number 1.
Command Execution in Subshells
Subshells allow for various command execution methods, enhancing control and flexibility.
Sequential Execution
Command:
(echo "First"; echo "Second")
Output:
First Second
Commands are executed sequentially within the subshell.
Parallel Execution
Command:
(echo "First" & echo "Second" &)
Output can vary, such as:
First Second
Or:
Second First
Commands run in parallel, so the order will vary.
Nested Subshells
Nested subshells are subshells created within other subshells, allowing for layered isolation and control.
Command:
(echo "Outer"; (echo "Inner"); echo "Again Outer")
Output:
Outer Inner Again Outer
This command demonstrates nesting by creating a subshell inside another subshell. The inner subshell prints “Inner”, while the outer subshell prints “Outer” and “Again Outer.”
Nested subshells can be used to create complex structures, isolate variables and functions, and build modular and maintainable code.
Using Subshells in Scripts
Subshells can add great flexibility and control in scripting by enabling conditional execution and looping.
Conditional Execution
Command:
if (exit 0); then echo "Success"; else echo "Failure"; fi
Output:
Success
The subshell exits with a status of 0, indicating success, so the “Success” branch of the conditional is executed.
Looping with Subshells
Command:
for i in 1 2 3; do (echo "Number $i"); done
Output:
Number 1 Number 2 Number 3
Here, a subshell is used within a loop to print numbers 1 through 3, demonstrating the flexibility of subshells in different control structures.
Efficiency of Subshells vs. Native Shell Commands
Subshells, while powerful and flexible, can have efficiency implications:
Creating a Subshell
Command:
time (echo "Subshell";)
Output:
Subshell real 0m0.001s user 0m0.000s sys 0m0.001s
Creating a subshell involves starting a new process, which can add overhead.
Using Native Shell Commands
Command:
time echo "Native Shell"
Output:
Native Shell real 0m0.000s user 0m0.000s sys 0m0.000s
Executing a command in the native shell usually requires less overhead.
This comparison emphasizes that, while subshells offer advantages like isolation and flexibility, they can also introduce efficiency concerns.
Real-World Example (Automation with Subshells)
Subshells can be incredibly useful in real-world scenarios, especially for automation. Here’s an example that demonstrates using subshells to automate a common task:
Backup Automation
Suppose you want to back up a directory and send a notification once done.
Command:
(tar -czvf backup.tar.gz /path/to/directory && echo "Backup successful" || echo "Backup failed") | mail -s "Backup Status" user@example.com
Output:
Backup successful
This command uses a subshell to create a compressed tar archive of the specified directory.
It then sends a success or failure notification to the specified email address.
This example highlights how subshells can be leveraged in real-world scenarios to automate complex tasks.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.