BASH Programming

Bash Export Command

If you’ve ever stood in front of a terminal, typed `declare -p` to see what is going on with your variables in bash, and hit enter, cool! You are going to be killing it with export in bash in no time. Here you will learn how to use export in and outside of bash scripts. Before you go off and kill any zombies in bash, it always helps if you know where to get help if in trouble. Here is what the help section for export looks like. Copy and paste. It’s not much to look but we’ll expand on it so that everything makes sense.

Command line

help export

Output

export: export [-fn] [name[=value] ...] or export -p

Set export attribute for shell variables.
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.

Options:

-f        refer to shell functions
-n        remove the export property from each NAME
-p        display a list of all exported variables and functions

An argument of `--' disables further option processing.

Exit Status:
Returns success unless an invalid option is given or NAME is invalid.

Great! Now you know all there is to know about bash export. Before you go and rack it up, here’s why you would consider using export over declare.

Why export?

There are plenty of reasons to not use export. After all, you can achieve the same result using declare or the command we don’t speak of, typeset. That is an argument on the opposing side.

On the other side, we may opt to use export. Most programmers are familiar with the practice of exporting variables to a subshell. It may provide an initial step up while learning bash programming.

In the middle, it wouldn’t hurt to be able to replace export with another command such as declare. Additionally, it would hurt less to use export in certain situations.

Since we already covered how to use the declare command previously, let’s just go through the list of equivalent expressions using both commands.

Export versus declare

If you can do it with export, you can do it with declare, or could you? Here we should you how to do everything in export using declare.

Export a variable or function

You can just as easily use declare in instead of export to add the export attribute to a variable or function. However, the converse is not true. Export does not allow modifications of attributes other than the export attribute.

Using export

Here two separate declares are required: the variable and the function used in the example that follows. Additionally, a declare line is also required to add the integer attribute to our variable.

If forehammer is mighty (greater than 9000), the anonymous function will produce the battle cry, “forehammer!”

export  forehammer
declare -i forehammer
 linuxhint="linuxhint.com"
test -d "${linuxhint}" || {
  git clone https://github.com/temptemp3/linuxhint.com
}
true() { test ! ${forehammer} -gt 9000 || echo "forehammer!" ; }
export -f true
_() { ( bash ${linuxhint}/true.sh ) ; } # forehammer!
forehammer=900 ; _ #
forehammer=9001 ; _ #  forehammer!

Note that the above example may be run as part of a bash script or in the terminal without comments.

Using declare

Here we salvage one line of code by using declare command to export variable and function in addition to adding other attributes. Forehammer!

declare -ix forehammer
linuxhint="linuxhint.com"
test -d "${linuxhint}" || {
  git clone https://github.com/temptemp3/linuxhint.com
}
true() { test ! ${forehammer} -gt 9000 || echo "forehammer!" ; }
export -f true
_() { ( bash ${linuxhint}/true.sh ) ; } # forehammer!
declare -xf true
forehammer=900 ; _ #
forehammer=9001 ; _ #  forehammer!

Note that the above example may be run as part of a bash script or in the terminal without comments.

List export variables and functions

Export and declare may be used interchangeably to list export variables and functions with the exception that listing export functions (name only) only works with declare. Otherwise, they work exactly the same when listing export variables and functions.
 
Let’s compare export and declare while performing the following operations:
 
[1] – list export variables
[2] – list export variable names with body
[3] – list export functions (name only)

Using export

Use export to list variables and functions names except the declare like listing of functions without the body. For that, you will need a workaround or use declare.

export -p  # [1] - list export variables
export -pf # [2] - list export function names with body
export -pF #[3] - (exit code 2)
export -pf | grep -e declare # [3] - workaround

Using declare

Use declare to list variable and function names without a workaround in the case of functions names only.

declare -px   # [1] - list export variables
declare -pxf  # [2] - list export function names with body
declare -pxF # [3] - list export functions (name only)

Remove the export attribute from variables and functions

The export attribute may be removed from functions and variables using either the export or declare command.

Using export

Here’s how to remove export attributes from a variable or a function using the export command. In the next example, we use export to add, remove, and list export variables, a through d.

Commands

_ ()
{
function __ ()
{
export -p | grep -e '\s\(a\|b\|c\|d\)$' | xargs
};
export a b c;
__;
export -n b;
__;
export -n c;
__;
export b c d;
__;
export -n a b c;
__
}
_

Note that the above example may be run in the terminal if you type or copy and paste.
Output

declare -x a declare -x b declare -x c declare -x d
declare -x a declare -x c declare -x d
declare -x a declare -x d
declare -x a declare -x b declare -x c declare -x d
declare -x d

Using declare

Here’s how to remove the export attribute from variables and functions using the declare command. . This example does the same thing as the above example only using declare.

_ ()
{
function __ ()
{
declare -px  | grep -e '\s\(a\|b\|c\|d\)$' | xargs
};
declare -x a b c;
__;
declare +x b;
__;
declare +x c;
__;
declare -x b c d;
__;
declare +x  a b c;
__
}
_

Output

declare -x a declare -x b declare -x c
declare -x a declare -x c
declare -x a
declare -x a declare -x b declare -x c declare -x d
declare -x d

Equivalent commands

Here are a list of export commands and their corresponding command using declare.

  1. export and declare -x
  2. export -p and declare -px
  3. export -n and declare +x
  4. export -f and declare -xf
  5. export -pf and declare -pxf
  6. export -nf and declare +xf

Export examples

No bash export command guide would be complete without examples. We have them here.

Cleanup export functions and variables in a script

Suppose that we want to remove all traces of export variables and functions in a bash script. Nothing you can’t do with the export command.

#!/bin/bash
## test-export-cleanup
## version 0.0.1 - initial
##################################################
test -d "sh2" || git clone https://github.com/temptemp3/sh2.git -b 190607
SH2=sh2
. ${SH2}/cecho.sh
list-exports() {
  {
    export -p
    export -pf
  } \
  | grep declare \
  | cut '-d ' '-f3' \
  | cut '-d=' '-f1'
}
cleanup-export() { { local name ; name="${1}" ; }
  {
     export -n  ${export}
     export -nf ${export}
   } 2>/dev/null
}
test-export-cleanup() {
  cecho yellow "exports: $( list-exports )"
  cecho green "cleaning up exports ..."
  for export in $( list-exports )
  do
   cleanup-export ${export}
  done
  cecho green "done cleaning up exports"
  cecho yellow "exports: $( list-exports )"
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-cleanup
##################################################
## generated by create-stub2.sh v0.1.2
## on Wed, 03 Jul 2019 23:07:31 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-cleanup.sh

Command

bash test-export-cleanup.sh

Output

exports: A B C f1 f2 f3
cleaning up exports ...
done cleaning up exports
exports:

Note that if the script is run in restricted mode, export functions are not included. We can modify the script above in order to run in restricted mode as follows.

#!/bin/bash
## test-export-cleanup
## version 0.0.1 - initial
##################################################
test -d "sh2" || git clone https://github.com/temptemp3/sh2.git -b 190607
SH2=sh2
. ${SH2}/cecho.sh
list-exports() {
  {
    export -p
  } \
  | grep declare \
  | cut '-d ' '-f3' \
  | cut '-d=' '-f1'
}
cleanup-export() { { local name ; name="${1}" ; }
  {
     export -n  ${export}
   }
}
test-export-cleanup() {
  echo "exports: $( list-exports )"
  echo "cleaning up exports ..."
  for export in $( list-exports )
  do
   cleanup-export ${export}
  done
  echo "done cleaning up exports"
  echo "exports: $( list-exports )"
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-cleanup
##################################################
## generated by create-stub2.sh v0.1.2
## on Wed, 03 Jul 2019 23:07:31 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-cleanup-restricted.sh

Export function for xargs

Running functions as part of a xargs command list require functions to be exported. You can use the export command.

#!/bin/bash
## test-export-xargs
## version 0.0.1 - initial
##################################################
test-export-xargs() {
fun() {
echo A${@}
}
export -f fun
seq 9 | xargs -i bash -c "fun {}" | xargs
seq 9 | xargs -i echo "fun {}" | bash | xargs
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-xargs
##################################################
## generated by create-stub2.sh v0.1.2
## on Fri, 05 Jul 2019 22:47:19 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-xargs.sh

Command line

bash test-export-xargs.sh

Output

A1 A2 A3 A4 A5 A6 A7 A8 A9
A1 A2 A3 A4 A5 A6 A7 A8 A9

Export all functions

You may want to export all functions instead of export all explicitly. Why not?

#!/bin/bash
## test-export-all-functions
## version 0.0.1 - initial
##################################################
a() { true ; }
b() { true ; }
c() { true ; }
test-export-all-functions() {
_() {
{
declare -Fx
declare -F
} | sort \
| uniq -c \
| grep -v -e '^\s*2\s' -e '_' \
| sed 's/.*-f\s//'
}
local function
for function in $( _ )
do
export -f "${function}"
done
declare -Fx
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-all-functions
##################################################
## generated by create-stub2.sh v0.1.2
## on Sun, 07 Jul 2019 16:18:26 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-all-functions.sh

Command line

bash test-export-all-functions.sh

Output

declare -fx a
declare -fx b
declare -fx c
declare -fx test-export-all-functions

Inspect export functions

You may want to inspect export function before running the payload of your script. After all, you wouldn’t want any commands to sneak into external commands.

#!/bin/bash
## test-export-inspect
## version 0.0.1 - initial
##################################################
test-export-inspect() {
test ! "$( export -f | grep eval )" || {
echo chaos detect 1>&2
echo exiting script ... 1>&2
exit 2 # chaos
}
echo life is good
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-inspect
##################################################
## generated by create-stub2.sh v0.1.2
## on Sun, 07 Jul 2019 16:40:13 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-inspect.sh

Commands

bash test-export-inspect.sh
chaos() { eval ${@} ; }
export -f choas
bash test-export-inspect.sh

Output

life is good
chaos detect
exiting script ...

Export all variables

You may want to go ahead and export all variables minus all the stuff you don’t need. Here’s how to do it using export in bash.

#!/bin/bash
## test-export-all-variables
## version 0.0.1 - initial
##################################################
A=
B=
C=
test-export-all-variables() {
local a
local b
local c
local variable
local temp
temp=$( mktemp )
_() {  # get list variables to export
declare -p | grep -v -e '-x' -e '[A-Z_]\+=\?' -e '^"$' -e 'variable' | cut '-d ' '-f3'
}
local variable
for variable in $( _ | tee ${temp} )
do
export ${variable}
done
declare -xp $( cat ${temp} )
}
##################################################
if [ ${#} -eq 0 ]
then
true
else
exit 1 # wrong args
fi
##################################################
test-export-all-variables
##################################################
## generated by create-stub2.sh v0.1.2
## on Sun, 07 Jul 2019 17:01:38 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: test-export-all-variables.sh

Commands

bash test-export-all-variables.sh

Output

declare -x a
declare -x b
declare -x c

Conclusion

Export is a builtin command that allows manipulation of export attributes for variables and functions. It can also be used to display names attributed to export. All export commands may be implemented using the declare command.

About the author

Nicholas Shellabarger

Nicholas Shellabarger

A developer and advocate of shell scripting and vim. His works include automation tools, static site generators, and web crawlers written in bash. For work he tools with cloud computing, app development, and chatbots. He codes in bash, python, or php, but is open to offers.