There’s more than one type of environment variable on Linux. Learn how to see them, create them for local and remote logins, and make them survive reboots.
How Environment Variables Work
When you launch a terminal window and the shell inside it, a collection of variables is referenced to ensure the shell is configured correctly. These variables also ensure that any information to which the terminal window and shell might need to refer is available. Collectively, these variables hold settings that define the environment you find inside your terminal window, right down to the look of the command prompt. So, naturally, they’re referred to as environment variables.
Some environment variables are system-wide, or global. Others are session-wide and can only be seen by you. Others can’t reference your session environment variables. There’s a third set of environment variables defined within the shell. Your locale, time zone, and keyboard settings, the set of directories searched when the shell tries to find a command, and your default editor, are all stored in shell environment variables.
We’re going to show you how to see the environment variables that exist on your system, and we’ll describe how to create your own. We’ll also show you how to make them available to child processes and to be persistent across reboots.
Environments and Inheritance
When a shell starts, it goes through an initialization phase. It’s at this point that it reads the environment variables that define the environment of the shell.
When a program or command is launched from that shell—known as a child process—it inherits the environment of the parent process—but watch out! As we’ll see, you can create variables that don’t get added to your environment, so they won’t be inherited by a child process.
If the child process is a shell, that shell will initialize from its own, fresh, set of variables. So, if you alter the command prompt in the current shell, and then launch a child shell, the child shell won’t inherit the modified command prompt of the parent.
Global Environment Variables
By convention, environment variables are given uppercase names. Here are some of the global environment variables, and what the values they contain represent:
- SHELL: The name of the shell that will launch when you open a terminal window. On most Linux distributions, this will be bash unless you changed it from the default.
- TERM: Terminal windows are actually emulations of a hardware terminal. This holds the type of hardware terminal that will be emulated.
- USER: The username of the current person using the system.
- PWD: The path to the current working directory.
- OLDPWD: The directory you were in prior to moving to the current working directory.
- LS_COLORS: The list of color codes used by the
lshighlight different file types.
- MAIL: If the
- PATH: A list of directories that the shell will search through to find command executables.
- LANG: The language, localization, and character encoding settings.
- HOME: The home directory of the current user.
- _: The underscore (
_) environment variable holds the last command that was typed.
RELATED: How to Use pushd and popd on Linux
We can see what some of these are set to using nothing more sophisticated than
echo, which will write the values to the terminal window. To see the value held by an environment variable, you need to add a dollar sign (
$) to the start of its name.
A nice touch is that you can use tab completion to fill in the environment variable name for you. Type a few letters of the name and hit Tab. The name of the variable is completed by the shell. If that doesn’t happen, you’ll need to type a few more letters to distinguish the environment variable from other commands with names that start with those same letters:
To create your own global environment variables, add them to the
/etc/environment file. You’ll need to use
sudo to edit this file:
sudo gedit /etc/environment
To add an environment variable, type its name, an equal sign (
=), and the value you want the environment variable to hold. Don’t space before or after the equal sign (
=). The name of the environment variable can contain letters, an underscore (
_), or numbers. However, the first character of a name cannot be a number.
If there are spaces in the value, be sure you enclose the entire value in quotation marks (
Save the file, and then log out and back in again. Use
echo to test that a new variable exists and holds the value you set:
Because it’s a global environmental variable, and available to everyone, user
mary can reference the environment variable when she next logs in:
To see all the environment variables at once, type
printenv. There’s a lot of output, so it makes sense to pipe it through
sort, and then into
printenv | sort | less
The sorted list of environment variables is displayed for us in
We can pipe the output through
grep to look for environment variables related to a particular topic.
printenv | grep GNOME
Shell Environment Variables
These are some of the shell environment variables used in
bash to dictate or record its behavior and functionality. Some of the values are updated as you use the terminal. For example, the
COLUMNS environment variable will be updated to reflect changes you might make to the width of the terminal window:
- BASHOPTS: The command-line options that were used when
- BASH_VERSION: The
bashversion number as a string of words and numbers.
- BASH_VERSINFO: The
bashversion as a digit.
- COLUMNS: The current width of the terminal window.
- DIRSTACK: The directories that have been added to the directory stack by the
- HISTFILESIZE: Maximum number of lines permitted in the
- HISTSIZE: Number of lines of
historyallowed in memory.
- HOSTNAME: The hostname of the computer.
- IFS: The Internal Field Separator used to separate input on the command line. By default, this is a space.
- PS1: The
PS1environment variable holds the definition for the primary, default, and command prompt. A set of tokens called escape sequences can be included in the definition of your command prompt. They represent such things as the host- and username, the current working directory, and the time.
- PS2: When a command spans more than one line and more input is expected, the secondary command prompt is shown. The
PS2environment variable holds the definition of this secondary prompt, which, by default, is the greater than sign (
- SHELLOPTS: Shell options you can set using the
- UID: The User Identifier of the current user.
RELATED: How to Use pushd and popd on Linux
Let’s check a few of these shell variables:
For the sake of completeness, here are the tokens you can use in the command prompt definitions:
- \t: The current time, formatted as HH:MM:SS.
- \d: The current date, expressed as weekday, month, date.
- \n: A new-line character.
- \s: The name of your shell.
- \W: The name of your current working directory.
- \w: The path to your current working directory.
- \u: The username of the person who’s logged in.
- \h: The hostname of the computer.
- \#: Each command within a shell is numbered. This allows you to see the number of the command in your command prompt. This is not the same as the number the command will have in the
- \$: Sets the final character of the prompt to a dollar sign (
$) for a regular user, and a hash symbol (
#) for the root user. This works by checking the UID of the user. If it’s zero, the user is root.
You’ll find the definition of your
PS1 environment variable in your
Creating Session Environment Variables
To create environment variables for your own use, add them to the bottom of your
.bashrc file. If you want to have the environment variables available to remote sessions, such as SSH connections, you’ll need to add them to your
.bash_profile file, as well.
The format of the environment variable definition is the same for both files. To add a definition to your
.bash_profile file, type this in your home directory:
We’ve added an environment variable called
INHERITED_VAR. Note the word “export” at the start of the line.
Save and close your file after you finish editing. You could log out and back in again, or you can cause the shell to re-read the
.bash_profile file using the dot command (
.) like this:
Now, let’s create an environment variable on the command line:
LOCAL_VAR="This session only"
If we use
echo, we can see that both environment variables are accessible to us:
You’ll notice the definition of the
INHERITED_VAR environment variable had the word “export” at the start of the line. This means the environment variable will be inherited by child processes of the current shell. If we launch another one using the
bash command, we can check the two variables again, from inside the child shell:
As you can see, the
INHERITED_VAR is accessible in the child shell, but
LOCAL_VAR is not. We simply get a blank line.
Although “export” adds the environment variable part to the environment that child processes inherit,
INHERITED_VAR is not a global environment variable. For example, user
mary cannot reference it:
To close our child
bash session, we use
Inherited environments affect scripts, too. Here’s a simple script that writes the values of our three environment variables to the terminal window:
#!/bin/bash echo "WEBSITE" $WEBSITE echo "LOCAL_VAR" $LOCAL_VAR echo "INHERITED_VAR" $INHERITED_VAR
This was saved to a file called
envtest.sh, and then made executable with the following:
chmod +x envtest.sh
When we run the script, it can access two out of three environment variables:
The script can see the
WEBSITE global environment variable and the
INHERITED_VAR exported environment variable. It cannot access
LOCAL_VAR, even though the script is running in the same shell where the variable was created.
If we need to, we can export an environment variable from the command line. We’ll do that to our
LOCAL_VAR, and then run the script again:
The environment variable has been added to the environment of the current shell, and so it appears in the environment that is inherited by the script. The script can reference that environment variable, too.
Global environment variables are accessible to remote login sessions, but if you want your locally defined environment variables available to you remotely, you must add them to your
.bash_profile file. You can set the same environment variable in the
.bash_profile files, with different values. This could be picked up by a script, say, to modify its behavior for people using the system locally or remotely.
(At the risk of confusing matters, there’s also a
.profile file. It can hold environment variable definitions, too. However, the
.profile file is not read if the
.bash_profile file is present. So, the safest thing to do—and the
bash-compliant way—is to use the
To edit the
.bash_profile file, we’ll use
We’re going to add the same environment variable with the same value we used before.
Save your changes and close
On another computer, we’ll make an
SSH connection to the test computer.
Once we’re connected, we’ll run the script once more:
.bash_profile file has been read as part of the initialization of the remote login, and the
INHERITED_VAR environment variable is accessible to us and the script.
Unsetting an Environment Variable
To unset an environment variable use the
unset command. If we unset the global environment variable,
WEBSITE, and the exported environment variable,
INHERITED_VAR, they’ll no longer be available on the command line, nor in child processes:
A point to note is this only changes the availability of global environment variables for you in this session. Another person who’s logged in simultaneously will still be able to access his instance of that global environment variable. His instance was initialized and read from the
/etc/environment file during his login process, and is independent of anyone else’s copy of the variable.
As an example, user
mary can still access the
WEBSITE environment variable and read its value, even though user
unset it in his session:
Environment variables can be used to let scripts and applications know how they should behave. They can be used to store settings or small amounts of data. For example, a script can populate an environment with a value that can be referenced by other scripts without having to write them to a file.