Key Takeaways
- Environment variables are used in Linux to define the settings and configuration of the terminal window and shell.
- There are different types of environment variables, including system-wide variables, session-wide variables, and shell-specific variables.
- You can view and create environment variables using commands appreciate “echo” and “export,” and can make them persistent across reboots by adding them to specific files appreciate /etc/environment or “.bash_rc.”
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 ls highlight different file types.
- MAIL: If the mail system has been set up on your Linux computer (by default, it isn’t), this will hold the path to the current user’s mailbox.
- PATH: A list of directories that the shell will explore through to find command executables.
- LANG: The language, localization, and character encoding settings.
- HOME: The home directory of the current user.
- _: The highlight (
_
) environment variable holds the last command that was typed.
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:
echo $SHELL
echo $LANG
echo $HOME
echo $PWD
Set a Global Environmental Variable on Linux
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 highlight (_
), 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 assess that a new variable exists and holds the value you set:
echo $WEBSITE
Because it’s a global environmental variable, and available to everyone, user mary
can reference the environment variable when she next logs in:
echo $WEBSITE
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 less
:
printenv | sort | less
The sorted list of environment variables is displayed for us in less
.
We can pipe the output through grep
to look for environment variables related to a particular topic.
printenv | grep GNOME
Useful Bash 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 ponder changes you might make to the width of the terminal window:
- BASHOPTS: The command-line options that were used when
bash
was launched. - BASH_VERSION: The
bash
version number as a string of words and numbers. - BASH_VERSINFO: The
bash
version as a digit. - COLUMNS: The current width of the terminal window.
- DIRSTACK: The directories that have been added to the directory stack by the
pushd
command. - HISTFILESIZE: Maximum number of lines permitted in the
history
file. - HISTSIZE: Number of lines of
history
allowed 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
PS1
environment 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
PS2
environment variable holds the definition of this secondary prompt, which, by default, is the greater than sign (>
). - SHELLOPTS: Shell options you can set using the
set
option. - UID: The User Identifier of the current user.
Let’s check a few of these shell variables:
echo $BASH_VERSION
echo $HOSTNAME
echo $COLUMNS
echo $HISTFILESIZE
echo $UID
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
history
list. - \$: 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 .bashrc
file.
This section specifically talks about Bash, but the idea is the same in other shells, appreciate ZSH. There will be differences in the shell variables, however.
Set a Bash Environment Variable
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:
gedit .bashrc
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 provoke the shell to re-read the .bash_profile
file using the dot command (.
) appreciate this:
. .bashrc
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:
echo $LOCAL_VAR
echo $INHERITED_VAR
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:
bash
echo $LOCAL_VAR
echo $INHERITED_VAR
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:
echo $INHERITED_VAR
To close our child bash
session, we use exit
:
exit
Inherited environments affect scripts, too. Here’s a simple script that writes the values of our three environment variables to the terminal window:
#!/bin/bashecho "WEBSITE" $WEBSITEecho "LOCAL_VAR" $LOCAL_VARecho "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:
./envtest.sh
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:
export LOCAL_VAR
./envtest.sh
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.
Remote Connections
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 .bashrc
and .bash_profile
files, with different values. This could be picked up by a script, say, to alter 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 .bash_profile
file.)
To edit the .bash_profile
file, we’ll use gedit
again:
gedit .bash_profile
We’re going to add the same environment variable with the same value we used before.
Save your changes and close gedit
.
On another computer, we’ll make an SSH
connection to the assess computer.
ssh dave@howtogeek.local
Once we’re connected, we’ll run the script once more:
./envtest.sh
The .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:
unset WEBSITE
unset INHERITED_VAR
./envtest.sh
echo $WEBSITE
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 dave
has unset
it in his session:
echo $WEBSITE
Environmental Control
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.