One of the concepts that often confuses Bash beginners is the difference between a normal shell variable and an exported variable. At first glance, they look almost identical, but they behave very differently when you start running other scripts or launching child processes.
The export command is used to make variables available outside of the current shell session. In other words, it allows child shells and processes to see and use the variables that you've created.
This becomes incredibly useful when you're writing larger Bash scripts that call other scripts or external programs and need to share information between them.
What Does the export Command Do?
The export command takes a variable that exists in your current shell and makes it available to any child processes that are started from it.
The basic syntax is very simple:
export VARIABLE_NAME="value"
For example:
export USER_NAME="Pavel"
Once exported, any child process or script that is executed from the current shell will be able to access the USER_NAME variable.
Without using export, the variable only exists in the current shell and cannot be seen by child processes.
Why Do We Need It?
Imagine you're writing a Bash script that needs to launch another Bash script.
You could pass values as command-line arguments, like this:
./second_script.sh "some_value"
This works perfectly fine for many situations.
However, sometimes you:
- Don't want to pass multiple parameters.
- Need to share several variables.
- Want external programs to access your variables.
- Need configuration values to be available everywhere.
This is where exported variables become extremely useful.
Understanding Child Processes
Before we continue, let's quickly talk about child processes.
Suppose you run a script:
./my_script.sh
Inside that script, you execute another script:
./another_script.sh
The second script runs inside its own process. It does not automatically inherit all the variables from the first script.
Only variables that have been exported are passed down to child processes.
Think of it like this:
Parent Script
|
|
v
Child Script
Normal variables stay in the parent.
Exported variables are passed down to the child.
Our First Example
Let's create two simple Bash scripts.
The first script will be called:
global_setter
The second script will be called:
global_getter
global_setter
#!/bin/bash
export GLOBAL_VAR="value of Global Parameter"
./global_getter
This script:
- Creates a variable called
GLOBAL_VAR. - Exports it.
- Executes another script.
global_getter
#!/bin/bash
echo "GLOBAL_VAR is $GLOBAL_VAR"
This script simply prints the value of the variable.
Running the Scripts
Make both scripts executable:
chmod +x global_setter
chmod +x global_getter
Now execute:
./global_setter
The output will be:
GLOBAL_VAR is value of Global Parameter
Everything works exactly as expected.
What Happens Without export?
Now let's remove the export keyword.
Instead of:
export GLOBAL_VAR="value of Global Parameter"
write:
GLOBAL_VAR="value of Global Parameter"
Save the file and execute it again:
./global_setter
The output will now be:
GLOBAL_VAR is
The variable exists perfectly fine inside the first script, but because it wasn't exported, the second script has no idea that it exists.
This is probably the easiest way to understand what export actually does.
Visual Explanation
Without export:
global_setter
|
|-- GLOBAL_VAR="Hello"
|
v
global_getter
GLOBAL_VAR is empty
With export:
global_setter
|
|-- export GLOBAL_VAR="Hello"
|
v
global_getter
GLOBAL_VAR is Hello
The only difference is the export keyword.
Exporting Variables in the Terminal
The export command isn't only useful in scripts.
You can use it directly from your terminal as well.
For example:
export PROJECT_NAME="AI Server"
Now check its value:
echo $PROJECT_NAME
Output:
AI Server
Any program or shell started from the current terminal session can now access this variable.
You can even see it from another Bash shell started from the current one.
Viewing Exported Variables
Sometimes it's useful to see all exported variables currently available in your shell.
The -p option prints all exported variables:
export -p
Example output:
declare -x HOME="/home/pavel"
declare -x LANG="en_US.UTF-8"
declare -x PATH="/usr/local/bin:/usr/bin"
You'll probably notice dozens of exported variables that Linux uses internally.
Some common examples include:
HOME
USER
PATH
LANG
PWD
SHELL
These are all environment variables that your operating system relies on.
Removing the Export Attribute
If you've exported a variable and later decide that you don't want child processes to see it anymore, you can remove its export attribute using the -n option.
Example:
export MY_VARIABLE="Hello"
Later:
export -n MY_VARIABLE
The variable still exists in your current shell, but it will no longer be exported.
This is a subtle but important distinction.
After running:
echo $MY_VARIABLE
you'll still get:
Hello
However, child processes will no longer receive it.
Exporting Functions
One of Bash's lesser-known features is that you can export functions as well.
The syntax looks like this:
my_function() {
echo "Hello from Bash!"
}
export -f my_function
Now the function can be inherited by child Bash processes.
This is particularly useful when working with:
- Bash automation
- GNU Parallel
- Docker entrypoint scripts
- Remote execution
- Advanced shell scripting
For beginners, you probably won't use exported functions very often, but it's nice to know the feature exists.
A Practical Example
Let's imagine you're building an installation script.
#!/bin/bash
export INSTALL_DIR="/opt/my_app"
export APP_VERSION="1.0.0"
./install_packages.sh
./configure_system.sh
./create_users.sh
Every child script automatically has access to:
INSTALL_DIR
APP_VERSION
without needing to pass them as command-line arguments.
This keeps your scripts:
- cleaner
- easier to maintain
- easier to expand
Common Beginner Mistakes
Forgetting to Export
Many beginners write:
MY_VAR="Hello"
./my_script.sh
and wonder why:
echo $MY_VAR
prints nothing inside the second script.
The solution is simply:
export MY_VAR="Hello"
Assuming Export Creates Global Variables
Another common misconception is that exported variables become globally available throughout the operating system.
They don't.
Exported variables are only inherited by child processes started from the current shell.
They are not shared:
- between terminal windows
- between users
- after a reboot
- across unrelated processes
Best Practices
Use exported variables when:
- Multiple scripts need the same configuration values.
- External programs need access to your variables.
- You want cleaner script interfaces.
- You're building larger Bash projects.
Avoid exporting variables unnecessarily. If a variable is only used inside a single script, there's no need to export it.
Keeping your environment clean is generally a good habit.
Final Thoughts
The export command is one of the fundamental building blocks of Bash scripting. Understanding how variables are inherited by child processes will save you countless hours of debugging later.
If you remember only one thing from this article, let it be this:
Normal variables stay in the current shell. Exported variables travel to child processes.
It's a simple idea, but once you understand it, writing larger and more modular Bash scripts becomes significantly easier.
In future articles, we'll explore more advanced Bash concepts, including positional parameters, local variables, return codes, and function arguments.