1. Introduction
When we read about different Linux bash commands and scripts, we often come across two different ways of defining a shell variable: with and without the export command. The simple addition of the export command while defining a bash variable changes the whole scope of that variable.
In this tutorial, we’ll discuss the differences between defining a bash variable with and without export.
We’ll also explore the different usages of the export command, its options, and related commands.
2. With export vs. Without export
Bash variables are very handy, just like variables in other programming languages, such as Java or C++. One major difference though is that they don’t need declaration; just assigning a value to the variable name creates a variable:
$ MYVAR=1729
$ export MYVAR=1729
The first definition creates a variable named MYVAR and assigns it the value 1729. This is a shell variable.
The second definition with the export command is another way of defining a variable. It creates a variable named MYVAR, assigns it the value 1729, and marks it for export to all child processes created from that shell. This is an environment variable.
The main difference between these two is that the export command makes the variable available to all the subsequent commands executed in that shell. This command does that by setting the export attribute for the shell variable MYVAR. The export attribute marks MYVAR for automatic export to the environment of the child processes created by the subsequent commands:
$ export MYVAR=1729
$ echo $MYVAR
1729
$ bash # Open a new child shell
$ echo $MYVAR
1729
Let’s contrast this with the shell variable defined without export, which is only available in that shell. Any child shells, processes, or subsequent commands can’t access it:
$ MYVAR=1729
$ echo $MYVAR
1729
$ bash # Open a new child shell
$ echo $MYVAR
$
If we compare bash variables to variables in programming languages:
- Shell variables (defined without export) are like local variables that we can access only within that shell.
- Environment variables (defined with export) are like global variables that we can access within the defining shell and all its child shells, processes, and commands.
However, if we compare bash environment variables to programming language global variables, there’s one main distinction. We can access bash environment variables only one way; the parent shell exports its variables to the child shell’s environment, but the child shell can’t export variables back to the parent shell.
3. Usage: to export or Not to export
We’ve just learned the difference between variable definitions with and without export. But when should we use export and when should we not use export?
We use environment variables (with export) when we want to export the variables and make them available to the subsequent commands or processes. Normally we use this to share the environment with a child process:
- Configure the environment of the child process or shell
- Define a variable that a bash script executed from the parent shell would use
- Setup environment variables for terminal multiplexers, like screen or tmux
- Configure build environment for build scripts and build tools
We use shell variables (without export) when we want the variables to be available only in the parent shell, and don’t want to pollute the child process’ environment:
- Loop counter variables
- Temporary variables
4. The export Command
Now let’s dive into more details of export and other related commands that we would frequently use when dealing with environment variables and shell variables.
4.1. Exporting Bash Functions
The export command can also export bash functions in addition to bash variables.
We can use the export -f command-line option to export functions so that they’re also available in child shells and processes:
$ func(){
> echo hi
> }
$ func
hi
$ bash # Open a new child shell
$ func
bash: func: command not found
$ exit # Back to parent shell
$ export -f func
$ bash # Open a new child shell
$ func
hi
4.2. Removing a Variable From export
The environment variables defined with export are automatically exported to all child shells, and to their child shells, and so on. But if we’re already in a child shell, we would’ve inherited some environment variables from our parent shell. If we don’t want to automatically export these variables to our child shells, export provides a command-line option -n to remove a variable from export:
$ echo $USER
ubuntu
$ bash # Open a new child shell
$ echo $USER
ubuntu
$ exit # Back to parent shell
$ export-n USER
$ bash # Open a new child shell again
$ echo $USER
$
4.3. Listing All Exported Variables
The export command without options or with the -p option displays a list of all variables and functions exported in the current shell:
$ export -p
declare -x COLORTERM="truecolor"
declare -x DESKTOP_SESSION="ubuntu"
declare -x DISPLAY=":0"
declare -x GDMSESSION="ubuntu"
declare -x LESSCHARSET="latin1"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s 2>&-"
.
.
declare -x XDG_SESSION_DESKTOP="ubuntu"
declare -x XDG_SESSION_ID="2"
declare -x XDG_SESSION_TYPE="x11"
declare -x XDG_VTNR="1"
This is quite useful to verify that we’re properly exporting the variables we define for export.
4.4. Automatically Export All Defined Variables
Sometimes it’s useful to automatically export all the variables that we define in the current shell. The bash shell option allexport helps us do this.
We can enable or disable it like any other bash shell option using the set command:
$ set -a # Enable allexport using single letter syntax
$ set -o allexport # Enable using full option name syntax
$ set +a # Disable allexport using single letter syntax
$ set +o allexport # Enable using full option name syntax
$ set -a
$ MYVAR=1729 # no export
$ bash # Open a new child shell
$ echo $MYVAR
1729
We often enable this shell option before calling a bash script that defines many variables without the export command.
5. Relation Between Parent Shell and Child Shells
When dealing with environment variables, we need to be aware of some points concerning the shell hierarchy of parent shell, child shell, child of child shell, and so on:
Parent Shell
Child Shell
The parent shell exports its variables to the child shell’s environment.
The child shell can’t export or modify variables back to the parent shell.
Variables exported by a child shell aren’t available in the parent shell.
Variables exported by the child shell are thereafter available only in the child of child shell, and so on.
The parent shell copies the exported variables and their values when creating the child shell.
The child shell maintains its copy of these environment variables.
6. Bash Scripting and export
When we create bash scripts containing the export commands, and call them from bash shell, we need to be sure we’re getting the expected result with the export command.
6.1. export While Running Bash Scripts
When we execute the bash scripts containing the export commands directly from the shell, or with the bash command, the scripts run in their own child shell. This means that any variables that the script exports will only be available to its child shells and not the parent shell. So when the script completes execution, the exported variables will disappear from the environment:
$ echo "export MYVAR=1729" > myscript.sh
$ chmod +x myscript.sh
$ ./myscript.sh
$ echo $MYVAR
$
6.2. source Variables From a Bash Script to the Current Shell
As we just saw, the bash script doesn’t export its exported variables back to the calling shell. To handle this special case, bash provides the source command. The source command, or the dot (.) command, executes the bash script in the current shell context without creating a child shell. Therefore, we don’t need the export command in the sourced script. The source command is useful to load variables and functions into the bash shell:
$ echo "MYVAR=1729" > myscript.sh
$ source myscript.sh
$ echo $MYVAR
1729
7. Conclusion
The Bash export command helps us to export environment variables so that they’re available in all child processes, shells, and commands. In addition, the different command-line options of the export command and other related commands provide various ways to define, export, and use bash variables across different shells and bash scripts.