[one-liner]: How to Use the Bash Shell’s export Command

Problem

Recently at my day job I’ve been having to go through some pretty old Bash scripts that I’ve basically inherited. As I’ve been going through them I’ve been seeing a lot of confusion as to the proper use of Bash’s export command. The major offense? Not really understand whether a particular variables needs to be exported, or not. So I thought I’d take a moment just to clarify when and when not to use export.

The export command has really only one true purpose. To mark and/or unmark variables (and functions) that you want to have automatically exported to environments of subsequently executed commands. So if you create a script that calls other commands, and you want to push variables into the environment of these commands, then you’ll want to use export.

Example #1 (without export)

For example, let’s say we have the following 2 scripts:

1
2
3
4
5
6
7
#!/bin/bash
# script #1: parent.bash
 
var1="this was set by the parent shell script"
echo "inside $0 script: $var1"
 
./child.bash
1
2
3
4
#!/bin/bash
# script #2: child.bash
 
echo "inside $0 script: $var1"

And when I run the script parent.bash I get this output:

1
2
3
4
5
# output from parent.bash & child.bash (without export)
 
% ./parent.bash
inside ./parent.bash script: this was set by the parent shell script
inside ./child.bash script:

Notice how the variable $var1, which was set in the parent.bash script, didn’t get displayed by the child.bash script? Now watch this example with the variable $var1 exported in the parent.bash script.

Example #2 (with export)

1
2
3
4
5
6
7
#!/bin/bash
# script #1: parent.bash
 
export var1="this was set by the parent shell script"
echo "inside $0 script: $var1"
 
./child.bash
1
2
3
4
#!/bin/bash
# script #2: child.bash
 
echo "inside $0 script: $var1"

And when we run parent.bash

1
2
3
4
5
# output from parent.bash & child.bash (with export)
 
% ./parent.bash
inside ./parent.bash script: this was set my the parent shell script
inside ./child.bash script: this was set my the parent shell script

Example #3 (un-exporting)

Export isn’t just a one trick pony. It can also unmark a previously exported variable.

1
2
3
4
5
6
7
8
9
#!/bin/bash
# script #1: parent.bash
 
export var1="this was set by the parent shell script"
echo "inside $0 script: $var1"
 
./child.bash
export -n var1
./child.bash
1
2
3
4
#!/bin/bash
# script #2: child.bash
 
echo "inside $0 script: $var1"
1
2
3
4
5
6
# output from parent.bash & child.bash (with a before/after export)
 
% ./parent.bash
inside ./parent.bash script: this was set by the parent shell script
inside ./child.bash script: this was set by the parent shell script
inside ./child.bash script:

Here we see the effects of the export -n on child.bash the 2nd time it’s called.

Which Variables are Flagged for Export?

You can use the command export -p to get a list of all the variables marked for export, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
% export -p
declare -x CCACHE_DIR="/var/cache/ccache"
declare -x CCACHE_UMASK="002"
declare -x COLORTERM="gnome-terminal"
declare -x CVS_RSH="ssh"
declare -x DESKTOP_SESSION="gnome"
declare -x DISPLAY=":0.0"
...
...
declare -x SHELL="/bin/bash"
declare -x SHLVL="4"
declare -x TERM="xterm"
declare -x USER="root"
declare -x WINDOWID="77021004"
declare -x XMODIFIERS="@im=imsettings"
declare -x var1="this was set by the parent shell script"

What else?

There is one additional trick related to exporting variables, but it doesn’t make use of the export command. It uses Bash’s set command. This command allows you to automatically export ALL the variables that have been modified or created to the environment of subsequent commands.

Here’s a quick example:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# script #1: parent.bash
 
# automatically export EVERYTHING
set -a
 
var1="this was set by the parent shell script"
var2="this was set by the parent shell too"
echo "inside $0 script: $var1"
echo "inside $0 script: $var2"
 
./child.bash
1
2
3
4
5
#!/bin/bash
# script #2: child.bash
 
echo "inside $0 script: $var1"
echo "inside $0 script: $var2"

Useful links

This entry was posted in bash, one-liner, shell, Syndicated, tip, tips & tricks. Bookmark the permalink.

Comments are closed.