DEV Community

dpm_bush
dpm_bush

Posted on Originally published at sshflow.com

Linux `export`: How Shell Variables Reach Other Commands

A variable you set in a terminal is not automatically available to every command you run. In Bash and other POSIX-compatible shells, export marks a variable so that commands launched afterward receive it in their environment.

That distinction matters when a script behaves differently from your interactive shell, or when you set a value and expect a separate program to see it.

Shell variable vs. environment variable

A shell can store a variable for its own use without passing it to child processes:

APP_MODE=development
Enter fullscreen mode Exit fullscreen mode

Check it in the current shell:

printf '%s\n' "$APP_MODE"
Enter fullscreen mode Exit fullscreen mode

But a new shell launched from that session does not inherit the value unless it was exported:

sh -c 'printf "%s\n" "${APP_MODE-unset}"'
Enter fullscreen mode Exit fullscreen mode

This prints unset. The variable exists in the parent shell, but it is not part of the environment that the parent passes to the child.

Export it when you assign it:

export APP_MODE=development
sh -c 'printf "%s\n" "$APP_MODE"'
Enter fullscreen mode Exit fullscreen mode

Now the child prints development.

You can also export a variable after assigning it:

APP_MODE=development
export APP_MODE
Enter fullscreen mode Exit fullscreen mode

The assignment sets the value; export APP_MODE marks it for inheritance by subsequently launched child processes.

Environment variables flow downward

Exporting is about process inheritance. A child process receives the exported environment when it starts. If that child changes a variable, the change does not flow back into the parent shell. And exporting a value now does not update processes that were already running.

For a one-off command, you can set a variable just for that command without changing the parent shell:

APP_MODE=development sh -c 'printf "%s\n" "$APP_MODE"'
Enter fullscreen mode Exit fullscreen mode

This is useful for testing a program under a particular setting. By contrast, export APP_MODE=development makes the variable available to later child commands launched from the current shell, too.

Common uses: PATH and application settings

A common reason to export a variable is to add a directory to PATH so commands launched from the shell can find programs there:

export PATH="$HOME/bin:$PATH"
Enter fullscreen mode Exit fullscreen mode

This prepends $HOME/bin while preserving the existing PATH. Only add directories you trust and can use. Running the command repeatedly in the same shell adds the directory repeatedly, so take care before putting it in a startup file that may be read more than once.

Applications may also read environment variables for configuration. For example, if your network provides an HTTP proxy, you might set:

export HTTP_PROXY="http://proxy.example:8080"
Enter fullscreen mode Exit fullscreen mode

That address is a placeholder; use the endpoint supplied for your environment. Applications vary in which proxy variable names they support, so check the application’s documentation. Avoid putting credentials in commands if they could be saved in your shell history.

Check, remove, or stop exporting a variable

In Bash and many POSIX shells, export -p lists variables marked for export:

export -p
Enter fullscreen mode Exit fullscreen mode

Review the output before sharing it: environment variables can contain sensitive values. To print just one value, use:

printf '%s\n' "$APP_MODE"
Enter fullscreen mode Exit fullscreen mode

An empty result does not tell you whether the variable is unset or set to an empty string. To distinguish those cases:

if [ "${APP_MODE+x}" ]; then
  printf 'APP_MODE is set\n'
else
  printf 'APP_MODE is not set\n'
fi
Enter fullscreen mode Exit fullscreen mode

To remove a variable entirely from the current shell, use unset:

unset APP_MODE
Enter fullscreen mode Exit fullscreen mode

In shells that support it, export -n APP_MODE removes the export attribute but retains the shell variable’s value. Future child processes will no longer inherit it.

Make a setting available in future shells

export changes the current shell environment; it does not make a setting permanent or system-wide. It also does not affect unrelated terminal windows. To have a variable set in future sessions, put an appropriate assignment in a startup file that the shell actually reads. Which file is right depends on the shell and whether it starts as a login or interactive shell.

After changing a startup file, open a new matching shell or source the file to apply the change to your current shell. Then check the value with printf. Be especially careful with startup-file changes to PATH: a typo can affect commands in every shell that reads that file.

If a script uses shell syntax, its interpreter matters: the shebang determines which shell runs it. See how to run a shell script in Linux for the distinction between invoking a script with a shell and running it directly. For Windows setups, choosing Bash or WSL can help clarify which shell is interpreting your commands.

When export is not recognized

export is a shell builtin in Bash and POSIX-compatible shells such as sh and dash; it is not a separate Linux package to install. If you see export: command not found, check that you entered the command at a shell prompt and that the expected shell is interpreting it. In Bash, type export identifies it as a builtin.

The practical rule is simple: assign a variable for use in the current shell; export it when future child processes need it. That small distinction explains many cases where a value appears in your terminal but not in the program you launch.

I originally published a more detailed version of this guide on the SSHFlow blog.

I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.

Top comments (0)