- How to Permanently Set $PATH in Linux
- Understanding the $PATH Variable
- Using bash_profile to Set your PATH
- Using bashrc to Set your PATH
- Free eBook: Git Essentials
- Using a Profile File to Set your PATH
- Permanently Setting your PATH for Other Shells like ZSH and KSH
- Permanently Setting System-Wide PATH for all Users
- Troubleshooting PATH Problems
- Where is the $HOME environment variable set?
- 5 Answers 5
- Environment variables
- Contents
- Utilities
- Defining variables
- Globally
- Per user
- Graphical environment
- Per session
- Using pam_env
- Examples
How to Permanently Set $PATH in Linux
Understanding the $PATH Variable
In this tutorial, we will show you how to permanently set your PATH on Linux.
First off, why should you care?
The $PATH variable, or just PATH, without the $ indicating variables, specifies a list of directories that impacts your computing platform’s functionality in a critical way. This is because the $PATH is the list of directories in which the system searches for executable programs, scripts, or files.
Imagine trying to run the ssh command, for example, to connect to a server. What happens if the system cannot find the ssh program? You are unable to connect to servers and run computations. You have a plethora of useful programs, examples like python , javac , npm , make , chmod , apt-get and so on, that your computer needs to be able to find when you invoke them at the command line.
The $PATH variable is the key that makes it possible to find the correct program and execute it at your command without needing the executable’s full directory path. When your PATH is set incorrectly, your shell will be unable to find programs, and certain commands will fail.
Using bash_profile to Set your PATH
A common mistake with the $PATH variable is to set it in the current shell only, without persisting the change. When you open a new shell, the changes are lost, and you are once again unable to execute certain commands because those programs are not found in the PATH.
The first way of setting your $PATH permanently is to modify the $PATH variable in your Bash profile file, located at /home/ /.bash_profile .
For example, let’s say I want to add a new directory /home/tomahawk/tools/jdk1.8.0_92/bin to my PATH. You might recognize this as a Java Development Kit installation. However, that is beside the point. Whatever the directory contains, I can add it to our path and make the programs that this bin directory contains accessible from the command line by adding the following line to the end of the file
A good way to edit the file is to use nano , vi , vim or emacs . You can use the command sudo
/.bash_profile , and enter your admin password when prompted, then add that line to the end and save the file.
To activate the changes in the current shell, you have to «source» the updated bash_profile file. You do this with the command:
This simply imports the file’s settings into the current shell. Now every time you open your shell, your bash_profile will automatically be «sourced» and you won’t need to run this command every time.
Now we can invoke commands or programs in the new directory /home/tomahawk/tools/jdk1.8.0_92/bin , such as javac , located at /home/tomahawk/tools/jdk1.8.0_92/bin/javac by just typing at the command prompt the name of the program. We can do this now from any directory, because the PATH has been updated to look for executable programs in our new directory.
Now runs the correct javac program, printing out something like the following:
bash_profile is appropriate when you want to set a PATH variable customized for a single user of the system. If you wanted to set PATH for all users of a system, there are better ways to do so, which we cover further on in this guide.
Using bashrc to Set your PATH
Instead of setting the PATH in
/.bash_profile , we can also add the directories we want to the PATH in
/.bashrc instead. Setting the PATH in bashrc looks identical to how we set it in bash_profile .
For example, to include the directory /home/tomahawk/.rbenv/bin in my path, I edit or create the file /home/tomahawk/.bashrc , adding the following line:
Notice that, like last time, the first thing in our new PATH export is the inclusion of the existing $PATH variable. This ensures that we preserve the current value of PATH, and just add any additional directories on to the PATH, after the $PATH variable. If you do not do this, you will overwrite the PATH variable entirely, and miss critical directories the system needs to be on the PATH. As a result, your system can become unusable.
Free eBook: Git Essentials
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
The difference between using bashrc and bash_profile is that bash_profile is used for login shells. These run when you login via the console, or log in using ssh . In contrast, once you are logged in, and you open a command shell or run the bash command, the bashrc file will run. Your PATH settings from bashrc will then be available.
The effect of setting the PATH is similar. In addition, we must activate any changes in the bashrc file into the current shell the first time we make this change, just as we did for the bash_profile file. This time, we run source
/.bashrc . We can now access the new PATH at the command line. It has been set permanently and will stay the same between multiple logins into the system.
Using a Profile File to Set your PATH
We can also set the PATH permanently using a user’s profile file. This is different from
/.bash_profile in that it is set not for shells only, but for all programs.
User profiles are loaded at login. The PATH variable can be set in the
To set my PATH to include everything already in $PATH, as well as a new directory /home/tomahawk/.exenv/bin , I edit the file at
/.profile and set the PATH as follows
As in all prior examples, we will need to source these changes to make them active for the current shell, but subsequent logins will persist the changes.
Once that’s done, I can run the exenv command, which is one of the programs available in the folder I just added to the PATH, and I get back the output of my exenv version:
You can read more about the exenv program here, but you can use this process to set PATH permanently to include any program or directory you want.
Permanently Setting your PATH for Other Shells like ZSH and KSH
If you use alternative shells such as zsh, ksh and others, you can set the PATH permanently using those shells’ configuration.
Like bash, both zsh and ksh use a zshrc and khsrc file, respectively, to set the path for non-login shells. For login shells, they use the analogous shell profile files zprofile and kprofile.
You can therefore set the PATH permanently for these shells in a similar way to what we did for Bash. For zsh, you can find these files, or create them if they do not exist, at
Similarly, you can set PATH permanently for ksh in the configuration files located at
There are plenty of other shells you can use, such as the C Shell and the tcsh shell. Setting the PATH permanently for them will generally follow the pattern we have seen here.
Permanently Setting System-Wide PATH for all Users
System-wide settings for all users can be set in /etc/profile . There is considerable flexibility and multiple options for setting the PATH permanently system-wide.
Your Linux system will execute all script files ending in .sh in /etc/profile.d whenever a bash shell is entered, as well as when the desktop session loads.
You can therefore add a new file, such as env.sh inside the directory /etc/profile.d . In this file, we can export the PATH variable, setting it permanently to our choice of path directories, for example:
Files in /etc/profile.d are sourced by /etc/profile, thus activating our system-wide PATH whenever a user logs in.
We can also set PATH for all users in /etc/environment , which takes key-value pairs of the form:
Troubleshooting PATH Problems
As we saw, setting the PATH permanently in Linux has many options. You can set the PATH for only a certain user, for all users, or for only certain types of command shells. However, it’s a good idea to not fiddle with system-wide PATH settings unless you really know what you are doing.
If you encounter problems, a good starting point is to find out the current value of $PATH, by running the command:
For more troubleshooting tips, check out this resource.
Where is the $HOME environment variable set?
I’m looking for the place where $HOME environment variable set. It is after login, to my mind.
I’m using Linux debian 2.6.32-5-686.
5 Answers 5
(it is defined in /etc/passwd ; edit it with usermod -d /some/new/home/dir myusername , though modifying the file may work)
(the string is passed in as an argument to the login program, which will later set the $HOME env var)
sidenote: When the $HOME variable is not defined, the bash shell will fetch it from its official definition in /etc/passwd and define it in that script. This may indicate that your scripting or programming language may have special treatment for the $HOME variable since it is slightly ‘important’ (though perhaps not as much as $PATH).
On Linux, the HOME environment variable is set by the login program:
- by login on console, telnet and rlogin sessions
- by sshd for SSH connections
- by gdm , kdm or xdm for graphical sessions.
The login program arranges it before calling exec on your shell (by including it in the arguments to exec), based on the value in /etc/passwd.
Edit this by running: usermod -d /home/whatever_dir whatever_user .
Please note that this will (obviously) be the new home directory. Bash will cd to it on login, so make sure it exists and the permissions are correct. In addition, don’t forget about .bashrc , .profile , .xinitrc , etc; if they’re not in the home directory, they will not be read.
I did some digging, and the answer to this is a bit surprising. Take the following test script and chmod +x it:
We can run it with ./test.sh and see:
Let’s take a peek under the hood with strace.
$ strace ./test.sh |& grep ‘^open[a-z]*’
openat(AT_FDCWD, «/etc/ld.so.cache», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libtinfo.so.5», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libdl.so.2», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libc.so.6», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/dev/tty», O_RDWR|O_NONBLOCK) = 3
openat(AT_FDCWD, «/usr/lib/locale/locale-archive», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache», O_RDONLY) = 3
openat(AT_FDCWD, «./test.sh», O_RDONLY) = 3
I do not see any mention of HOME, rc files, or passwd. Let’s try it with a clean env:
Nothing, as expected. Let’s run the script in the blank env.
Interesting, the script is able to get home. Now let’s trace.
openat(AT_FDCWD, «/etc/ld.so.cache», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libtinfo.so.5», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libdl.so.2», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libc.so.6», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/dev/tty», O_RDWR|O_NONBLOCK) = 3
openat(AT_FDCWD, «/etc/nsswitch.conf», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/etc/ld.so.cache», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libnss_compat.so.2», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/etc/ld.so.cache», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libnss_nis.so.2», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libnsl.so.1», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/lib/x86_64-linux-gnu/libnss_files.so.2», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «/etc/passwd», O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, «./test.sh», O_RDONLY) = 3
I’ve bolded the interesting lines. As we can see, it would appear that when $HOME is not defined, the shell will try to fill it in, even when not in login or interactive mode.
Environment variables
An environment variable is a named object that contains data used by one or more applications. In simple terms, it is a variable with a name and a value. The value of an environmental variable can for example be the location of all executable files in the file system, the default editor that should be used, or the system locale settings. Users new to Linux may often find this way of managing settings a bit unmanageable. However, environment variables provide a simple way to share configuration settings between multiple applications and processes in Linux.
Contents
Utilities
The coreutils package contains the programs printenv and env. To list the current environmental variables with values:
The env utility can be used to run a command under a modified environment. The following example will launch xterm with the environment variable EDITOR set to vim . This will not affect the global environment variable EDITOR .
The shell builtin set(1p) allows you to change the values of shell options, set the positional parameters and to display the names and values of shell variables.
Each process stores their environment in the /proc/$PID/environ file. This file contains each key value pair delimited by a nul character ( \x0 ). A more human readable format can be obtained with sed, e.g. sed ‘s:\x0:\n:g’ /proc/$PID/environ .
Defining variables
Globally
Most Linux distributions tell you to change or add environment variable definitions in /etc/profile or other locations. Keep in mind that there are also package-specific configuration files containing variable settings such as /etc/locale.conf . Be sure to maintain and manage the environment variables and pay attention to the numerous files that can contain environment variables. In principle, any shell script can be used for initializing environmental variables, but following traditional UNIX conventions, these statements should only be present in some particular files.
The following files can be used for defining global environment variables on your system, each with different limitations:
- /etc/environment is used by the pam_env module and is shell agnostic so scripting or glob expansion cannot be used. The file only accepts variable=value pairs.
- /etc/profile initializes variables for login shells only. It does, however, run scripts and can be used by all Bourne shell compatible shells.
- Shell specific configuration files — Global configuration files of your shell, initializes variables and runs scripts. For example Bash#Configuration files or Zsh#Startup/Shutdown files.
In this example, we will create a function to add several directories (e.g.
/scripts ) to PATH for the respective user. To do this, just put this in your preferred global environment variable configuration file ( /etc/profile or /etc/bash.bashrc ):
Per user
You do not always want to define an environment variable globally. For instance, you might want to add /home/my_user/bin to the PATH variable but do not want all other users on your system to have that in their PATH too. Local environment variables can be defined in many different files:
To add a directory to the PATH for local usage, put following in
To update the variable, re-login or source the file: $ source
/.bashrc etc. This means that, for example, dbus activated programs like Gnome Files will not use them by default. See systemd/User#Environment variables.
Graphical environment
If an environment variable only affects graphical applications, you may want to restrict the scope of it by only setting it within the graphical session.
To set environment variables only for a specific application instead of the whole session, edit the application’s .desktop file. See Desktop entries#Modify environment variables for instructions.
Using a startup script
Some graphical environments, (e.g. KDE Plasma) support executing shell scripts at login: they can be used to set environment variables. See KDE#Autostart for example.
Xorg environment
The procedure for modifying the environment of the Xorg session depends on how it is started:
/.xsession ; see XDM#Defining the session.
SDDM additionally sources startup scripts for login shells, like
/.bash_profile for bash or
Though the end of the script depends on which file it is, and any advanced syntax depends on the shell used, the basic usage is universal:
Wayland environment
Since Wayland does not initiate any Xorg related files, GDM and KDE Plasma source systemd user environment variables instead.
No other display managers supporting Wayland sessions (e.g. SDDM) provide support for this yet. However, SDDM sources startup scripts for login shells on Wayland sessions too.
Per session
Sometimes even stricter definitions are required. One might want to temporarily run executables from a specific directory created without having to type the absolute path to each one, or editing shell configuration files for the short time needed to run them.
In this case, you can define the PATH variable in your current session, combined with the export command. As long as you do not log out, the PATH variable will be using the temporary settings. To add a session-specific directory to PATH , issue:
Using pam_env
The PAM module pam_env(8) loads the variables to be set in the environment from the following files in order: /etc/security/pam_env.conf and /etc/environment .
/.zshenv .
The deprecated
/.pam_environment is not read anymore. See FS#68945.
/etc/environment must consist of simple VARIABLE=value pairs on separate lines, for example:
/etc/security/pam_env.conf has the following format:
@
The format also allows to expand already defined variables in the values of other variables using $<VARIABLE> , like this:
VARIABLE=value pairs are also allowed, but variable expansion is not supported in those pairs. See pam_env.conf(5) for more information.
Examples
The following section lists a number of common environment variables used by a Linux system and describes their values.