Setting PATH variable in /etc/environment vs .profile
Solution 1:
Summary:
-
If you want to add a path (e.g.
/your/additional/path
) to yourPATH
variable for your current user only and not for all users of your computer, you normally put it at the end of~/.profile
like in one of those two examples:PATH="/your/additional/path:$PATH" PATH="$PATH:/your/additional/path"
Note that the path priorities are descending from left to right, so the first path has the highest priority. If you add your path on the left of
$PATH
, it will have the highest priority and executables in that location will override all others. If you add your path on the right, it will have the lowest priority and executables from the other locations will be preferred. However, if you need to set that environment variable for all users, I would still not recommend touching
/etc/environment
but creating a file with the file name ending in.sh
in/etc/profile.d/
. The/etc/profile
script and all scripts in/etc/profile.d
are the global equivalent of each user's personal~/.profile
and executed as regular shell scripts by all shells during their initialization.
More detail:
/etc/environment
is a system-wide configuration file, which means it is used by all users. It is owned byroot
though, so you need to be an admin user and usesudo
to modify it.~/.profile
is one of your own user's personal shell initialization scripts. Every user has one and can edit their file without affecting others./etc/profile
and/etc/profile.d/*.sh
are the global initialization scripts that are equivalent to~/.profile
for each user. The global scripts get executed before the user-specific scripts though; and the main/etc/profile
executes all the*.sh
scripts in/etc/profile.d/
just before it exits.
-
The
/etc/environment
file normally contains only this line:PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
It sets the
PATH
variable for all users on the system to this default value, which should not be changed in a major way. At least you should not remove any of the important paths like/bin
,/sbin
,/usr/bin
and/usr/sbin
from it.This file is read as one of the first configuration files by every shell of every user. Note that it is not a shell script. It is just a configuration file that gets parsed somehow and that may only contain environment variable assignments!
-
The
~/.profile
file can contain many things, by default it contains amongst other stuff a check whether a~/bin
directory exists and adds that to the user's existingPATH
variable, like this (on older Ubuntu releases prior to 16.04 -- which adds it unconditionally -- and on 18.04, which also adds "~/.local/bin"):# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
You see that the old value of
PATH
gets reused here and the new path is only appended to the beginning instead of overwriting everything. When you manually want to add new paths, you should also always keep the old$PATH
value somewhere in the new string.This initialization script is read only by the shells of the user to which it belongs, but there's another condition:
# ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists.
So if you use the default Bash shell, you should make sure that you don't have a
~/.bash_profile
or~/.bash_login
if you want the changes in~/.profile
to have an effect for your user.
For a full understanding on Environment Variables see: https://help.ubuntu.com/community/EnvironmentVariables
Related question: difference between bash.bashrc and /etc/environment file
Solution 2:
This answer is mainly about the order in which environment variables like
PATH
are assigned when specified in different configuration files. I do also cover where you should usually set them, but the list below does not list files in the order that you should consider using them. For general information on settingPATH
and other environment variables in Ubuntu, I also recommend reading EnvironmentVariables and the other answers to this question.
The preferred place to set PATH
depends on which users you need to set it for and when and how you want it to be set. Part of your decision will be whether you want an environment variable set for all users or on a per-user basis. If you're not sure, then I recommend setting it for just one user (e.g., your account) rather than systemwide.
As AlexP says, the PATH
environment variable will have the value it was most recently assigned. In practice, most of the time you set PATH
, you include the old value of PATH
in the new value, so that the previous entries are retained.
Thus, in practice, when PATH
is set from multiple files, it usually contains the entries given in all the files. But that only happens because all files that set it, except the first one, usually reference the PATH
variable itself, causing its old value to be included the new one.
Therefore, you are in effect asking for the order in which PATH
settings in various files take effect.
Common, general-purpose places to set PATH
are listed below in the order in which they take effect when a user logs in, not in the order you should typically consider using them. Each of the places listed below is a reasonable choice for setting PATH
in some situations, but only a few are good choices most of the time.
In the list below, you'll see some directory names like ~/.profile
. In case you're unfamiliar with tilde expansion, ~/
refers to the current user's home directory. I mainly use this syntax for compactness. It is supported in shell scripts, but not in PAM configuration files.
1. For all users: /etc/environment
PAM on Ubuntu causes environment variables listed in /etc/environment
to be set, if that file exists, which by default it does. That's how environment variables for all users are most commonly set.
$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
If you must set environment variables for all user accounts, rather than just your user account, then modifying that file is likely your best choice. I recommend backing it up first. One way to back up this file is to run:
sudo cp /etc/environment /etc/environment.orig
The .orig
extension is not specifically required -- you can feel good about naming the backup file anything that's not confusing or already being used. (Besides .orig
, .old
, .backup
and .bak
are common.)
You can edit this file in any of the ways you might edit any other file as the root user (sudoedit /etc/enviromnment
, sudo nano -w /etc/environment
, gksudo gedit /etc/environment
, etc.)
/etc/environment
doesn't support including the old value of a variable automatically. But this is usually unnecessary, since most of the time you would set an environment variable for all users by editing /etc/environment
, you would want that to be its initial value when the user logs in, anyway. The user could then change it as they like. Typically it is good for users to be able to do this.
2. For all users: /etc/security/pam_env.conf
PAM reads environment variables for all users from /etc/security/pam_env.conf
, specified with the same syntax as used in per-user ~/.pam_environment
files (see below).
When the same environment variable is set in both /etc/environment
and /etc/security/pam_env.conf
, the value in pam_env.conf
is used -- even if that value is specified as DEFAULT
rather than OVERRIDE
.
However, when you supersede a line in environment
with one in pam_env.conf
, you can include the contents of the superseded value. See the section below on .pam_environment
for details (since it uses the same syntax).
It's not usually necessary to edit pam_env.conf
and you should be very careful if you do, since a malformed line will usually prevent all normal user accounts from logging in at all! For example, the default pam_env.conf
contains the lines:
#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
This is presented as one of several examples. One of the things it illustrates is how to split an assignment across multiple lines with \
. Suppose you were to uncomment just the first line, but forgot to uncomment the second line:
PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
Don't do this!
I just tested that myself by accident, and it prevented any users from logging in successfully. To fix it, I had to boot in recovery mode and change it back. (Fortunately I did this on a virtual machine I use only for testing things, so it didn't cause me any trouble.)
3. For one user: .pam_environment
in the user's home directory
One of the ways to set an environment variable for a single user is for that user to edit (or create) .pam_environment
in their home directory. Values set in this file supersede those set in the global /etc/environment
file.
.pam_environment
is not part of the skeleton of files that is copied into a user's home folder when the user account is initially created. However, if you create that file in your home directory, you can use it to set environment variables like PATH
. Unlike /etc/environment
(but like /etc/security/pam_env.conf
), the per-user .pam_environment
files do support expanding the old value of an environment variable into a new one. They are not shell scripts, however, and you must use a special syntax to achieve this, which differs somewhat from the syntax you would use in a file like .profile
.
For example, if you had a bin2
directory in your home directory that you wanted to add to the end of PATH
, you could do that by adding this line to .pam_environment
:
PATH DEFAULT=${PATH}:/home/@{PAM_USER}/bin2
See the ~/.pam_environment
subsection of EnvironmentVariables (from which the above example is closely adapted), man pam_env
, and man pam_env.conf
for further details.
Although this was once touted as the preferred way for Ubuntu users to change or add environment variables and is still considered a reasonable and acceptable choice, you should be careful when editing .pam_environment
. Like edits to the systemwide /etc/security/pam_env.conf
(see above), a malformed line in a user's .pam_environment
file will prevent logins from succeeding. (I have tested this -- on purpose this time.) For information about how the recommendations have evolved, see Gunnar Hjalmarsson's comments below and this ubuntu-devel
discussion.
Such a mistake is much less serious, in general, than a malformed line in pam_env.conf
, because it affects only one user. However, in the case of a desktop Ubuntu system with only one user account that allows logins, such a mistake while editing .pam_environment
will be just as bad as a mistake editing pam_env.conf
-- if you're not already logged in, you won't be able to fix it without booting in recovery mode (or from a live USB, etc.).
(If you do have other user accounts, then you can log in as another user and fix the problem. Even if they're not an administrator and cannot sudo
to root, they can still run su your-account
and be prompted to enter your (not their) password. The guest account, however, cannot do this, as it is prohibited from using su
to take on the identity of another user.)
4. For all users: /etc/profile
and files inside /etc/profile.d/
Bourne-compatible shells (including bash
, the default user shell in Ubuntu) run the commands in /etc/profile
when invoked as a login shell.
Ubuntu's /etc/profile
ends with:
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
This causes the commands in any file in the /etc/profile.d/
directory whose name ends in .sh
to be run as well.
Most display managers cause the commands in /etc/profile
(and thus files in /etc/profile.d
) to be run for graphical logins too. However, not all do, and that's a significant argument in favor of using the facilities provided by PAM instead (see above) -- unless there will never be any graphical logins to this system, which might be the case, for example, if it's a server with no GUI installed.
It's traditional to set systemwide environment variables in /etc/profile
, but this is often not the best choice anymore. If you cannot set an environment variable in /etc/environment
, and you must set it for all users, then it's probably better to make a new file in /etc/profile.d/
than to edit /etc/profile
itself. One reason for this is that, when Ubuntu is upgraded, there may be a new default /etc/profile
file. Depending on how you perform the upgrade, either the old file (with your changes) will be kept, foregoing that particular updated configuration file, or you will be prompted to handle the situation.
When the same environment variable is set in both /etc/profile
and one or more files in /etc/profile.d
, which is performed last? This depends on whether the commands in /etc/profile
that set them appear before or after the files in profile.d
have been sourced (by the code I've quoted above). Commands in /etc/profile
are executed in the order they appear.
/etc/profile
is a shell script, and its syntax is not the same as that of the PAM configuration files discussed above. Its syntax is the same as the syntax for the per-user ~/.profile
file (see below).
If you need to write code that decides whether or not to add a particular directory to PATH
(and to do so for all users), you won't be able to use /etc/environment
or /etc/security/pam_env.conf
to do that. This is perhaps the main situation where it is better to to use /etc/profile
or /etc/profile.d/
instead.
5. For one user: .bash_profile
in the user's home directory
If a user has ~/.bash_profile
, bash uses it instead of ~/.profile
or ~/.bash_login
(see below). You should not usually have a .bash_profile
in your home directory.
If you do, it usually ought to contain a command to source ~/.profile
(e.g., . "$HOME/.profile"
). Otherwise, the contents of the per-user .profile
file aren't run at all.
6. For one user: .bash_login
in the user's home directory
If a user has ~/.bash_login
, bash uses it instead of ~/.profile
(see below), unless ~/.bash_profile
exists, in which case neither of the others will be used unless sourced from `~/.bash_login.
As with .bash_profile
, you should not usually have a .bash_login
file in your home directory.
7. For one user: .profile
in the user's home directory.
When a Bourne-style shell is run as a login shell, it runs the commands in /etc/profile
(which typically includes commands that cause the commands in files in /etc/profile.d/
to be run -- see above). After that, it runs the commands in .profile
in the user's home directory. This file is separate for every user. (Bash actually runs .bash_profile
or .bash_login
instead if they exist -- but, for users on an Ubuntu system, those files rarely should or do exist. For details, see above and 6.2 Bash Startup Files in the Bash manual.)
~/.profile
is thus the main place for user to put commands that run when they log on. It is the traditional place for you to set your PATH
, but since Ubuntu has the pam_env module and supports ~/.pam_environment
, you should consider using that.
As with /etc/profile
, not all display managers run this file for graphical logins, though most do. This is a reason to prefer ~/.pam_environment
for setting environment variables (much as one may prefer /etc/environment
to /etc/profile
).
You can expand environment variables, including PATH
itself, when you set PATH
in .pam_environment
(see above). However, if you need to set PATH
in a more sophisticated way, you might have to use your .profile
instead. In particular, if you want to check if a directory exists every time a user logs in and only add it to PATH
if it does, then you won't be able to use your .pam_environment
file to add that directory to your PATH
.
For example, the default per-user .profile
file on Ubuntu used to end with:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
See Gunnar Hjalmarsson's comment on Byte Commander's answer for details.
This checks if you have a bin
subdirectory of your home directory. If so, it adds that subdirectory to the beginning of your PATH
.
That list omits some possibilities.
There are other ways environment variables are set when users log in that depend more heavily on the type of login. For example, you may occasionally have environment variables that get set just for graphical logins or just for SSH-based remote logins. The list above does not cover such cases.
I've left out a few files where people sometimes define environment variables, like ~/.bashrc
and /etc/bash.bashrc
, because they are not generally recommended places to set PATH
and it is rare that you should actually use them for this purpose. If you use these files to add directories to PATH
, then they will sometimes be added many times and is very confusing when you examine $PATH
. (In extreme cases this may slow things down, but usually it's just a matter of keeping everything clean and understandable.)
Since bash
is Ubuntu's default login shell for users, and most users use it or some other POSIX-compatible shell, I've omitted information about how environment variables are set in other, non-Bourne-style shells such as tcsh
.