In Linux based systems you can set dynamic named values as environment variables. Those values are stored within the system and are used by command line applications. To put it simply, an environment variable is a variable with a name and an associated value. A variable is a symbol, letter, or a word such as "x" or "y," that represents a value.
The environment variable can store information about the default text editor or browser, the path to executable files, etc...
An environment variable is globally available, in a program and its child programs. A shell variable is only available in the current shell.
In this tutorial, we will explain how to list and set the environment and shell variables.
Environment Variables
Environment variables are variables that are available system-wide and are inherited by all spawned child processes and shells.
The environment variables are implemented as strings that represent key-value pairs. If multiple values are passed, they are typically separated by colon (:) characters. Each pair will generally look something like this:
KEY=value1:value2:value3
The names of the variables are case-sensitive and are usually used in an upper case format (MYVAR1, MYVAR2...)
If the value contains white-space, quotations are used:
KEY="value with spaces"
Shell Variables
Shell variables are variables that are contained exclusively within the shell in which they were set or defined. Each shell such as zsh and bash, has its own set of internal shell variables. They are usually used to keep track of ephemeral data, like the current working directory. Usage is the same as with the global environment variables.
To make a shell variable available as an environment variable, use export MYVAR:
$ export MYVAR=linoxide.com $ echo $MYVAR linoxide.com $ env | grep MYVAR MYVAR=linoxide.com
Common Environmental and Shell Variables
Some environmental and shell variables are very useful and are referenced fairly often. Here are some common environmental variables that you will come across:
TERM | This specifies the type of terminal to emulate when running the shell. Different hardware terminals can be emulated for different operating requirements. You usually won’t need to worry about this though. |
USER | The current logged in user. |
PWD | The current working directory. |
OLDPWD | The previous working directory. This is kept by the shell in order to switch back to your previous directory by running cd -. |
LS_COLORS | This defines color codes that are used to optionally add colored output to the ls command. This is used to distinguish different file types and provide more info to the user at a glance. |
The path to the current user’s mailbox. | |
PATH | A list of directories that the system will check when looking for commands. When a user types in a command, the system will check directories in this order for the executable. |
LANG | The current language and localization settings, including character encoding. |
HOME | The current user’s home directory. |
_ | The most recent previously executed command. |
In addition to these environmental variables, some shell variables that you’ll often see are:
BASHOPTS | The list of options that were used when bash was executed. This can be useful for finding out if the shell environment will operate in the way you want it to. |
BASH_VERSION | The version of bash being executed, in human-readable form. |
BASH_VERSINFO | The version of bash, in machine-readable output. |
COLUMNS | The number of columns wide that are being used to draw output on the screen. |
DIRSTACK | The stack of directories that are available with the pushd and popd commands. |
HISTFILESIZE | Number of lines of command history stored to a file. |
HISTSIZE | Number of lines of command history allowed in memory. |
HOSTNAME | The hostname of the computer at this time. |
IFS | The internal field separator to separate input on the command line. By default, this is a space. |
PS1 | The primary command prompt definition. This is used to define what your prompt looks like when you start a shell session. The PS2 is used to declare secondary prompts for when a command spans multiple lines. |
SHELLOPTS | Shell options that can be set with the set option. |
UID | The UID of the current user. |
List Shell and Environment Variables
There are several commands available that allow you to list environment variables in Linux:
env – The command allows you to run another program in a custom environment without modifying the current one. When used without an argument it will print a list of the current environment variables.
printenv – The command prints all or the specified environment variables.
set – The command sets or unsets shell variables. When used without an argument it will print a list of all variables including environment and shell variables, and shell functions.
In their default state, env and printenv should function exactly the same:
$ printenv SSH_CONNECTION=10.0.2.2 37182 10.0.2.15 22 LESSCLOSE=/usr/bin/lesspipe %s %s LANG=C.UTF-8 XDG_SESSION_ID=5 USER=vagrant MYVAR=linoxide.com PWD=/home/vagrant HOME=/home/vagrant SSH_CLIENT=10.0.2.2 37182 22 XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop SSH_TTY=/dev/pts/0 MAIL=/var/mail/vagrant TERM=xterm-256color SHELL=/bin/bash SHLVL=1 LOGNAME=vagrant XDG_RUNTIME_DIR=/run/user/1000 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin LESSOPEN=| /usr/bin/lesspipe %s _=/usr/bin/printenv
The difference between env and 'printenv' commands is only apparent in their more specific functionality. For instance, with 'printenv', you can request the values of individual variables:
$ printenv SHELL /bin/bash $ printenv HOME /home/vagrant $ printenv MYVAR linoxide.com
env command lets you modify the environment in which programs are running, by passing a set of variables into a command:
env MYVAR=linoxide.com command_to_run command_options
The printenv and env commands print only the environment variables. If you want to get a list of all variables, including environment and shell variables, and shell functions you can use the set command:
$ set BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_COMPLETION_VERSINFO=([0]="2" [1]="8") BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="4" [2]="20" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") BASH_VERSION='4.4.20(1)-release' COLUMNS=140 DIRSTACK=() EUID=1000 GROUPS=() HISTCONTROL=ignoreboth HISTFILE=/home/vagrant/.bash_history HISTFILESIZE=2000 HISTSIZE=1000 HOME=/home/vagrant HOSTNAME=ubuntu-bionic HOSTTYPE=x86_64 IFS=$' \t\n' LANG=C.UTF-8 LESSCLOSE='/usr/bin/lesspipe %s %s' LESSOPEN='| /usr/bin/lesspipe %s' LINES=35 LOGNAME=vagrant .....
The command will display a large list of all variables so you probably want to pipe the output to the less command.
set | less
Set Shell and Environment Variables
Commands available to set environment variables in Linux are:
set – The command sets or unsets shell variables. When used without an argument it will print a list of all variables including environment and shell variables, and shell functions.
unset – The command deletes shell and environment variables.
export – The command sets environment variables.
To better understand the difference between shell and environmental variables we’ll start with setting shell variables and then move on to the environment variables.
We will begin by defining a shell variable within our current session. You can verify that the variable is set by using echo $MYVAR
$ MYVAR=Linoxide $ echo $MYVAR Linoxide
Use the printenv command to check whether this variable is an environment variable or not:
$ printenv MYVAR
No output should be returned. This means that MYVAR variable is not an environment variable.
The export command is used to set Environment variables.
To create an environment variable simply export the shell variable as an environment variable:
$ export MYVAR
You can check this by running:
$ printenv MYVAR Linoxide
You can also set environment variables in a single line:
$ export MYNEWVAR="My New Variable"
Environment variables created this way are available only for the current session. If you open a new shell, or if you log out, all variables will be lost.
We can also revert an environment variable to shell variable, or even completely (unset) remove it:
Our MYVAR variable is defined as an environmental variable. We can change it back into a shell variable by typing:
$ export -n MYVAR
It is no longer an environmental variable, however, it is still a shell variable.
If we want to completely unset a variable, either shell or environmental, we can do so with the unset command:
$ unset MYVAR
We can verify that it is no longer set:
$ echo $MYVAR
Nothing is returned because the variable has been unset.
Persistent Environment Variables
We’ve already mentioned that many programs use environmental variables to decide the specifics of how to operate. We do not want to have to set important variables up every time we start a new shell session,
The bash shell reads different configuration files depending on how the session is started.
An interactive shell session is a shell session that is attached to a terminal. A non-interactive shell session is one is not attached to a terminal session.
One distinction between different sessions is whether the shell is being spawned as a “login” or “non-login” session.
In most Linux distributions when you start a new session, environment variables are read from the following files:
/etc/environment - Use this file to set up system-wide environment variables.
/etc/profile - Variables set in this file are loaded whenever a bash login shell is entered.
~/.bashrc - Per-user shell specific configuration files. For example, if you are using Bash, you can declare the variables there.
To load the new environment variables into the current shell session use the source command:
$ source ~/.bashrc
If you need to set system-wide variables, you may want to think about adding them to /etc/profile, /etc/bash.bashrc, or /etc/environment.
Conclusion
In this tutorial, we have learned how to set and list environment and shell variables. These variables are always present in your shell sessions and can be very useful for many programs. There are plenty of other, more mundane, but more common scenarios where you will need to read or alter the environment of your system. If you have any questions, please feel free to leave them in the comments below.