1. Introduction

Bash, which stands for Bourne Again SHell, is a powerful tool that lets users interact with the operating system through a rich set of commands. Every shell, including bash, maintains an environment, which, according to the Bash Reference Manual, is a list of name-value pairs of variables of the form name=value passed to a program when executed. 

Ensuring a clean environment is important when running programs in bash, especially when testing code or troubleshooting issues since it minimizes interference from pre-existing variables or shell configurations set in our current session.

In this tutorial, we’ll explore how to run a program in a clean environment in bash.

2. Shell vs. Environment Variables

We should first distinguish between the two main types of variables in a shell.

The environment variables are global in that all shells share them started after the variable is defined; thus, they act as a system-wide configuration for all bash shells. Also, they are inherited by child shells.

We can look at all environment variables used in bash by running the env command with no arguments. As we’ll see later, env is a handy command when we want to manipulate the environment, too. The exact output of the env command will vary depending on your system configuration and any environment variables you have set. However, here’s an example of what you might see:

In contrast, shell variables are local, meaning they are only present in the current bash session in which they were defined and don’t persist or influence child processes, like launched scripts, in any way. We can see the shell variables (which include environment variables) by running the set command with no arguments

3. Where Do Environment Variables Come From?

Before trying to eliminate all the variables from our environment, we should first examine where they come from and see what are some common ones.

3.1. Export/Declare

Bash provides several ways to manipulate the environment, the most common being the export and declare commands, which allow variables to be added, and unset, which allows variables to be deleted:

export TEST=foo and unset TEST

3.2. Inline

We can also set variables inline when executing a command by prepending the variable definition:

$ TEST=foo; echo $TEST

3.3. Startup Files

Apart from these methods, though, when bash is invoked, it first reads and executes commands from some startup files. First, bash searches and executes the file /etc/profile, if that file exists. Afterward, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. These files may, and they usually do, contain environment variables.

3.4. .bashrc

Bash’s runcom file, more commonly known as .bashrc, is also executed when a new bash session is started, which is also a possible source of unwanted environment variables.

3.5. Parent Shell

A bash shell also inherits all environment variables from the shell’s parent in the environment:

$ export MY_VAR="parent_value"
$ bash -c 'echo "Child MY_VAR: $MY_VAR"'
Output: Child MY_VAR: parent_value

4. Common Environment Variables

Some common environment variables we have probably seen before are:

Variable

Explanation

USER

Our current user’s name

SHELL

The path to the current command shell (for example, /bin/bash)

PWD

The current working directory.

HOSTNAME

The hostname of the computer

HOME

The home directory

PATH

A colon-separated list of directories that are searched when the shell looks for commands to run

5. How to Achieve a Clean Environment

Now that we understand the various sources of environmental variables in Bash, let’s see how to achieve a clean environment for program execution.

5.1. Completely Clean Environment

If we want a completely clean environment, we can run env -i command. This runs a command in an empty environment, discarding all exported variables from our current session and all inherited variables from the parent process. We can verify this by running env -i env which prints all the environment variables, which in this case will be none.

$ env -i env
# Nothing is displayed.

Another way to achieve the same result with a script is to first print all variables and then unset them one by one:

unset $(env | awk -F= '{print $1}')

The env command, as we discussed before, prints all the environment variables with their corresponding values in the form name=value. First, we pipe the output of env to the awk text processing tool, which prints only the variable name. Finally using command substitution $() we pass all the environment variables as the argument to unset, which removes them.

5.2. Exclude Only Startup and Profile Files

If we just want to discard the variables exported by ~/.bashrc or the profile startup files, we can start our bash session with the options –norc or –noprofile, respectively.

$ bash --norc --noprofile -c env
SHELL=/bin/bash
USER=your_username  
HOME=/home/your_username
TERM=xterm-color
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Many more lines depending on your specific environment variables

6. Conclusion

In this article, we explored the concept of a clean Bash environment and various methods to achieve it. We began by understanding the role of environment and shell variables within bash, highlighting the distinction between global and local variable scopes. Next, we saw where all the environment variables contained in our bash sessions come from, and finally, we presented various techniques to achieve different levels of ‘cleanness’ in our environment.