How is the path environment variable managed in Linux/Ubuntu/Debian?

Many users, beginners and advanced are sometimes confused on how the PATH environment variable is handled on Linux. Why there are so many files .bash_profile, .bashrc,.profile , .bash_login ?
In this short article, we will try to clear up this confusion and will also explain how to add a path to PATH on Linux as well as provide a glimpse into the different files involved and the way they are invoked.

PATH environment variable

We all know that when you type in a command in the terminal on Linux, we are instructing the kernel to run the corresponding program. For example common commands like cd, echo, rm are simply short programs that are usually located inside /usr/bin.

Other executable programs can be found inside /usr/local/bin or /usr/sbin…In general, these type of programs can reside practically anywhere on the system, i.e. they do not have a specific directory.

When a command is invoked, the kernel does not need to search in every folder its corresponding program since it relies on the $PATH environment variable which informs the kernel about the whereabouts of the correct program.

Read: Environment Variables in Python

In order to be able to execute some programs that may have been installed in other uncommon directories on your machine, you could easily indicate their location by adding a directory to your $PATH. To find out what is inside your $PATH, run the command below :

echo $PATH

Ubuntu environment variables

You will most likely see the directories that were mentioned earlier along with some others. You could notice that the entries are separated by colons.

How a path is added to PATH ?

The answer to how a new path is added to the PATH environment variable can be the following for instance : using the files

PATH=$PATH:~/opt/bin or PATH=~/opt/bin:$PATH         [set environment variable linux | linux add to path]

This however will depend on whether the user wants to add ~/opt/bin at the end (to be searched after all other folders or directories if a program with the same name exists in multiple folders) or at the start (to be searched rather before all other folders).

Read : How to fix high memory usage in Linux

Multiple entries can be added at the same time. PATH=$PATH:~/opt/bin:~/opt/node/bin or other variations on the ordering will work just fine.

For example, to add directory /data/bashscripts to the start of the $PATH environment variable, proceed as follows:

PATH=/data/bashscripts:$PATH.           [how to set path in ubuntu]

To add it to the end, use the following command:

PATH=$PATH:/data/bashscripts             [add to path linux]

Once you add the path to the $PATH and reboot, your change is gone. This is a standard behavior (see next section).

If the PATH gets constructed by different components, this might lead to duplicate entries. Some distributions actually put ~/bin in the PATH automatically if it exists.

How to permanently add a directory to $PATH

Insert the line to modify PATH in the file ~/.profile or in ~/.bash_profile (in case you do not care about shells different from bash) if it exists. You would need to source this in order for it to persist:

source ~/.profile

In general and depending on the final goal, there are various ways that allow users to permanently add a directory to $PATH.

The variable values are stored usually in either a shell script that is run at the start of the system or user session or in a list of assignments. You must use a specific shell syntax and set or export commands in case of the shell script .

Read : How to keep Ubuntu clean

Scope : User’s session

A – ~/.profile, ~/.<shell>_profile, ~/.<shell>_login Shell script. Only programs executed from terminal will be able to read these. A suitable option for systems that are shell-only.
For instance the content of ~/.profile applies session wide like programs that you start once the user logs in ( not graphical programs) and environment variable definitions. If you log in via a GUI, you do not get a login shell that reads the file ~/.profile automatically. Depending on the window manager, the graphical login program or desktop environment you execute later on and how your Linux system configured these applications, the file ~/.profile may or may not be read.

The .bash_profile is used to initialize the shell upon login and to setup variables as well as aliases. Instead of ~/.profile, ~/.bash_profile can be used.

Shells that are in login mode will be able to use these files.

B~/.xprofile. Shell script. When the user logs into X Window System, this is executed.
By default .xprofile does not exist in your home folder unless you create one. This is
Ideal for extending PATH with common values like ~/bin or ~/go/bin or specifying user defined OWNPATH or NODE_HOME. The instructions for making a .xprofile file can be found here. The defined variables can be ‘seen’ by every X application. Do not use the syntax of your own user shell but rather use POSIX shell syntax, since the file is included by other scripts.

C – ~/.<shell>rc. Shell script. This is a rather bad choice since it is specific to a single shell. Used in non login mode.
The content of ~/.bashrc for instance applies to bash only, like for instance function definitions, aliases , prompt settings and shell options. It is the settings file of interactive instances of bash. There are some recommendations to either insert the definitions of the environment variables in ~/.bashrc or launch login shells in terminals. These are not good ideas since the environment variables will only be set in programs invoked via the terminal not in programs launched directly with a menu or an icon or keyboard shortcut

Read: what is the difference between non login and login non interactive and interactive shell sessions in linux ubuntu debian

Scope: System

A – /etc/environment.d/*.conf : Ideal for adding system wide folders such as /usr/local/folder/bin to PATH or creating ANDROID_HOME. The setting can be divided up into different files, one for every tool (NodeJs,Java, Go..).
The environment.d directories In general, contain a set of global environment variable assignments that are specific to the user environment. These folders are parsed and read by systemd-environment-d-generator which passes it to the systemd user manager instance.

B – /etc/environment : is not a script file, but it contains assignment expressions lines. It stores system wide locale as well as path settings. Ideal for adding system wide folders such as /usr/local/folder/bin to PATH or creating ANDROID_HOME. Used by SystemD and PAM(Pluggable Authentication Module).

C – /etc/profile and /etc/profile.d/* Shell script. An acceptable choice for systems that are shell-only. The file /etc/profile for instance contains global configuration for login shells that are either interactive or not . Every time you log in to your Linux system, bash runs the commands in the startup file /etc/profile. The /etc/profile.d directory has other scripts that contain startup files that are application specific and which are also executed at startup time by the shell. Only shells in login mode would read these files.

D – /etc/xprofile Shell script. Is run during the start of X Window System session. This is executed for every logged-in user into X Window System. For PATH entries that are valid for each user, it is a suitable option for PATH, like for example /usr/local/folder/bin. Use POSIX shell syntax and not the syntax of your own user shell, since the file is included by other scripts.

E – /etc/<shell>.<shell>rc. Shell script. This is a rather bad choice since it is specific to a single-shell.Used in non login mode.

Read: Ubuntu/Debian monitoring tools guide for system administrators

Wrapping up

At any time, you can launch a shell directly, for instance by opening a terminal emulator within a GUI environment. As mentioned above, it doesn’t read the file ~/.profile, If the shell is not a login shell. When bash is run as an interactive shell (i.e., not to execute a script), it reads the file ~/.bashrc (except when invoked as a login shell), then it only reads the files ~/.bash_profile or ~/.profile.

From Bash man page, we can read:

This can be summarized by the nice chart below :

You start a login shell when you first access or log-in to your system in order for bash to read the files mentioned in the excerpt above. Most Linux distributions set a system wide $PATH (applies to all users) at /etc/profile where any change made, will apply to all users.

Once the user is logged in and opens a terminal, this will start an interactive, non-login shell. This is what we find in the documentation provided by man bash:

In a nutshell, those files are accessed and read every time the user opens a new terminal. The final $PATH is actually the combination of the values in all the files.

At this level, the $PATH is whatever value was defined or specified in the different profile files. If the user opens a terminal, then he is in an interactive shell and the various bashrc files are read which may insert things to the $PATH.

If you like the content, we would appreciate your support by buying us a coffee. Thank you so much for your visit and support.


amin nahdy

Amin Nahdy, an aspiring software engineer and a computer geek by nature as well as an avid Ubuntu and open source user. He is interested in information technology especially Linux based ecosystem as well as Windows and MacOS. He loves to share and disseminate knowledge to others in a transparent and responsible way.

Leave a Reply