Variables provide a simple way to share configuration settings between multiple applications and processes in Linux, and are mainly set in either a terminal or shell configuration file upon start up.
They are either environmental or shell variables by convention. Both of which are usually defined using all capital letters. This helps users distinguish environmental variables from within other contexts.
As said there are technically one of two categories a variable can fall into:
“Environment variables” have been defined for use in the current shell and will be inherited by any child shells or processes spawned as a result of the parent. Environmental variables can also be used to pass information into processes that are spawned by the shell.
“Shell variables” are contained exclusively within the shell in which they were set or defined. They are mostly used to keep track of ephemeral temporal data, like the current working directory in a session.
To see all currently set environment variables in a terminal type:
Alternatively the shorter command
env works too:
To see individual or specific environment variables and print with standard output use either of the following:
$ printenv TERM
Prints multiple variables.
$ printenv SHELL USER
echo prints contents.
$ echo $TERM
Which can print multiple variables too.
$ echo $LANG $HOME
To output shell variables as well as environment variables using
set do the following:
$ set | less -N
set is usually used to change or unset shell options and parameters but here we have piped the command through less to see what it outputs instead of allowing it to make changes.
The command can be modified to not show the residual bash functions included in the last output (using posix mode). The brackets also indicate that the process will be run in a sub shell so that
set does not actually change anything in the current shell’s environment.
$ (set -o posix; set) | less -N
Note that there is no one command for retrieving only what we class as shell variables. One way of getting these as output is with a sorted comparison from both of the two previous
env commands. This is not one hundred percent accurate however.
$ comm -23 <(set -o posix; set | sort) <(env | sort) | less -N
In the last command
comm is used to compare the output of
set in a sub shell with the output of
env in a sub shell, before finally being fed through
less . The two compared outputs are also sorted with
This is how the system knows what shell to be used when interpreting commands. In most Linux systems Bash is the default primary shell, but many others can be installed on the system and assigned to this variable.
This specifies the type of terminal to emulate when running the shell. The default in GUI based desktop environments is often
Is set to the username of the currently logged in Linux user.
pwd command it contains the currently active working directory.
The last working directory the user moved from. The shell uses this when the
cd - command is invoked.
ls command has built-in colour support used to differentiate between file types and folders. Colour codes are stored in this variable that determine the colours used.
The shell’s main “Path” variable holds a list of directories that the system will query when looking for commands/programs the user types in. They are checked in the order listed.
The currently set language and localization in use (locales), including character encoding.
The current user’s home directory.
The previously executed command and its path.
The shell’s preferred text editor.
The shell’s preferred pager program.
Contains the location of incoming email. The traditional path is used as an example here.
The list of options that the shell included when bash was run. Useful for finding out if the shell environment currently can do what you expect it to.
$ echo $BASHOPTS
The version of bash being executed, in human-readable form.
$ echo $BASH_VERSION
Similar to the last variable except in “machine“ readable format.
$ echo $BASH_VERSINFO
The number of columns that are being used to draw output to the screen.
$ echo $COLUMNS
The stack of directories that are available with the
$ echo $DIRSTACK
Number of lines of command history that gets stored to the file per bash session.
$ echo $HISTFILESIZE
The number of lines of command history maximum to be stored in memory.
$ echo $HISTSIZE
The hostname of the computer at this time.
$ echo $HOSTNAME
The internal field separator character that separates input on the command line. By default, this is a space so there is no real output to show as an example command.
The primary command prompt’s definition. Defines quint-essentially what your prompt looks like when you start a shell session.
$ echo $PS1
Any shell options that can be or have been set with the set option.
$ echo $SHELLOPTS
The assigned UID of the current user.
$ echo $UID
To create a shell variable in the current shell session, specify a name and a value in the same manner as usual in Bash. Adhering to the naming convention of using full capitals for the variable name.
$ EXAMPLE_VAR='hello world!'
Note the single quotation marks used since the string content of our variable contains a space.
Also when special characters like
! are used in the string, apostrophes must be inserted instead of double quotes to enclose the the string.
! is special character in Bash as it is usually used to expand the shell history.
We can see the newly defined variable by using
$ echo $EXAMPLE_VAR
As said this is only a shell variable within the current Bash session and not an environmental variable.
This can be checked by using
$ printenv EXAMPLE_VAR
No output is returned as the definition is not recognised as part of the environment.
Let’s take this as an opportunity to demonstrate a way of accessing the value of any shell or environmental variable.
Remember like in these example that to reference the value of a variable, precede it with a
$ sign. This is so the shell knows to substitute the name of the variable for it’s content.
To create one, export an existing shell variable into the shell’s persistent environment using the
$ export EXAMPLE_VAR
This time when we check the variable with
printenv it will output.
$ printenv EXAMPLE_VAR
The variable now descends into a sub shell child process and is retained from the parent, test this by starting anew shell session with
To bypass having to set a variable and then export it to the environment, the process can be combined like this:
$ export INSTANT_ENV_VAR="instant definition plus export!"
Return to the parent shell we came from with
exit , and try to
echo the previously exported variable:
Notice no output is returned as environment variables can only be passed to child processes, and not the other way around. This is sensible for the most part as it “prevents programs from affecting the operating environment from which they were called”.
Also when you exit back into your main parent shell, the child shell environment is destroyed.
To change an already set environment variable back into a lesser shell variable use the
-n parameter with
$ export -n EXAMPLE_VAR
Now nothing is returned when using
printenv on the variable:
$ printenv EXAMPLE_VAR
It’s still set as a shell variable so to undefine it completely from this local shell session you can use:
$ unset EXAMPLE_VAR
To create predefined variables at login depends upon how bash is started and which configuration file it uses to do so. The deciding factors on which file is used relies on the types of “login shell” that have being initiated by the user.
The types being either:
- Login or Non-Login
- Interactive or Non-Interactive
So the two distinctions that are taken into account are whether the shell is being spawned as a “login” or “non-login” session. As well as whether the session is either an “interactive session” or “non-interactive” session.
A login shell is a shell session that always begins by authenticating the user. If you are signing into a terminal session or through SSH and authenticate, your shell session will be classed and set as a “login” shell.
A session started as a login session will read configuration details from the
/etc/profile file first, and then look for the first login shell configuration file it can find in the user’s home directory. In order to get user-specific configuration details.
These files are the first it can find out of
~/.bash_login , and
If you start a new shell session from within your authenticated session, like earlier when we called the
bash command from the terminal, a non-login shell session is started. This is as you were were not asked for any authentication details when you started the child shell.
A session defined as a non-login shell will always read
/etc/bash.bashrc and then the user-specific
~/.bashrc file to help build its environment.
An interactive shell session is a shell session that is attached to a terminal and in use. So a normal session that begins with SSH is usually defined as an interactive login shell. See “Non Interactive” in the next section to see the difference between the two.
A non-interactive shell session is one that is not attached to a terminal session, and not currently in use. For example a script run from the command line is usually run in a non-interactive, non-login shell.
Most notable non-interactive shells read the environment variable named
BASH_ENV and read the file specified in this variable to construct the new shell environment.
So there are a variety of circumstances that dictate which of the different files are needed to set predefined variables.
This has it’s advantages and gives a lot of flexibility for specific situations where you might want only certain settings for a login shell, and other different settings in a non-login shell.
Despite this to make things easier and more general, most people most of the time will want the same settings for both scenarios.
Depending upon your Linux distribution and personal setup, usually the login configuration files source the non-login configuration files. Meaning that you don’t have to define the variables in both files and can get away with defining environment variables that you want in both only inside the non-login configuration files. They will then be read in both scenarios as they’re sourced in the latter.
It’s also best to set them for your individual user and not system wide. so to make them available to both login and non-login shell sessions define these variables in the
An example of the line to set a persistent environment variable in the
.bashrc file would look like this:
$ export EXAMPLE_VAR='hello world!'
Which is the same as before whilst on the command line.
The next time you start a shell session, your environment variable declaration(s) are always read and passed on to the shell’s environment (including subsequent child shells too).
You can force your current session to read the config file at any time by typing in a terminal:
$ source ~/.bashrc
To set them in the system wide files if you prefer, do the same except add the variable definition(s) to:
/etc/bash.bashrc , or
- Digital Ocean - How to Read and Set Environmental and Shell Variables on a Linux VPS
- Arch-wiki - Environment Variables Page
Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b
– Scarlz: @5car1z