What is Subshell in Linux?
You are already aware of shell. It is a program that lets you run commands in Linux. Your major interaction with shell is when you are running commands in a terminal.
Sooner or later, you'll come across a term called 'subshell' and that may confuse you.
What is a subshell?
A subshell is basically a new shell just to run a desired program. A subshell can access the global variables set by the 'parent shell' but not the local variables. Any changes made by a subshell to a global variable is not passed to the parent shell.
Does that make sense? Probably not. Let me explain things in detail with examples.
Here's a one line script that displays the value of variable 'var'.
echo $var
I set the value of this variable to LHB, what do you think will be displayed when the script is run?
Surprise! The script doesn't see the value of variable var
I had set earlier.
Shell scripts run in subshell (by default)
Why? Because when you run a shell script, it runs into its own shell. Since this shell originates from another shell (where you set the variable and where you run the script), it is called a subshell.
The shell script couldn't see the value of the variable because it was a local variable, and it was not known to the newly created shell. If you want the variable to be accessed by its subshells, you'll have to use the export command and turn it into a global variable.
You can also create subshell by launching new shells from your existing shells. Just run bash
and you'll be in a subshell. You can use the exit command to close/exit the shell and move back to the original shell.
Don't think of subshell as a new terminal window. I know it is difficult to visualize but that's how it is.
I used the variable to show the difference between the two shells (parent and the subshell). The variable var
was not exported in this case and hence it was not known to the subshell.
Nested subshells
You can create nested subshells as well, in the same manner. After a variable is exported, it remains exported to all subshells created subsequently.
You can change the value of the exported variable in a subshell. The changed value will be passed to the subsequent subshells (because the variable itself is a global one) but if you exit it and go back to the original shell, the original value is retained.
Why? Because the value of the exported variable is copied to the subshell. And it is the copy which is changed (from LHB to HOC). The original value remains the same in the parent shell.
So keep this in mind, there is no way to change the value of a variable in a parent shell from within a subshell. It doesn't matter if you export the variable or not, the variable won't be changed in the parent shell.
Bonus Tip: Execute a shell script in the current shell
The normal behavior is that a shell script is executed in its own shell i.e. a subshell.
You may change this behavior and run a shell script in the current shell thanks to the built-in shell command called dot (.).
No, it is not the same as running a shell script like this ./script. Instead, you run it like this:
. script
This way, commands from the script are executed by the current shell as if they were typed into terminal instead of being run via a script in a subshell. Scripts can access the local variables this way.
I think that's a good enough information about subshell in Linux.
Do you have a better understanding of it now or are you confused more than ever? Feel free to express yourself in the comments as an LHB member.