Quick Links

Key Takeaways

  • Your PATH is a list of locations that your operating system checks when running a command, allowing you to run executables without manually specifying their exact location.
  • The shell searches for executables in the PATH in a specific order, starting with shell builtins, then searching through the listed directories from left to right.
  • You can add directories to your PATH using the export command, either temporarily or permanently by editing your .bashrc or .profile files. Just be careful not to add a leading colon to avoid security risks.

PATH is one of the silent manipulators in the background of your Linux computer. It quietly affects your user experience, but there's nothing shady about it. We'll explain what it does, and how you can adjust it.

What Is PATH on Linux, and How Does It Work?

Your PATH is a list of locations that your operating system will check any time you attempt to run a command. If an executable that you attempt to run is contained in a folder that is included in your PATH the executable can be run without specifying its exact location manually, since your operating system already knows where it is.

So how does it actually work functionally?

When you type a command in a terminal window and press Enter, you kick off quite a lot of activity before your command is even executed.

Bash is the default shell on most Linux distributions. It interprets the line of text you entered and identifies the command names intermingled with the parameters, pipes, redirections, and whatever else is there. It then locates the executable binaries for those commands and launches them with the parameters you supplied.

The first step the shell takes to locate the executable is identifying whether a binary is even involved. If the command you use is within the shell itself (a "shell builtin") no further search is required.

Shell builtins are the easiest to find because they're integral to the shell. It's like having them in a toolbelt — they're always with you.

If you need one of your other tools, though, you have to go rummage in the workshop to find it. Is it on your workbench or a wall hanger? That's what the PATH environment variable does. It holds a list of places the shell searches and the order in which they'll be searched.

If you want to see whether a command is a shell builtin, an alias, a function, or a standalone binary mv /work/unfile, you can use the type command as shown below:

type clear

type cd

type clear in a terminal window

This tells us that clear is a binary file, and the first one found in the path is located at /usr/bin. You might have more than one version of clear installed on your computer, but this is the one the shell will try to use.

Unsurprisingly, cd is a shell builtin.

How to List Your PATH

It's easy to see what's in your path. Just type the following to use the echo command and print the value held in the $PATH variable:

echo $PATH

echo $PATH in a terminal widnow

The output is a list of colon (:) delimited file system locations. The shell searches from left to right through the path, checking each file system location for a matching executable to perform your command.

We can pick our way through the listing to see the file system locations that will be searched, and the order in which they will be searched:

  • /usr/local/sbin
  • /usr/local/bin
  • /usr/sbin
  • /usr/bin
  • /sbin
  • /bin
  • /usr/games
  • /usr/local/games
  • /snap/bin

Something that might not be immediately obvious is the search doesn't start in the current working directory. Rather, it works its way through the listed directories, and only the listed directories.

If the current working directory isn't in your path, it won't be searched. Also, if you have commands stored in directories that aren't in the path, the shell won't find them.

To demonstrate this, we created a small program called rf. When executed, rf prints the name of the directory from which it was launched in the terminal window. It's located in /usr/local/bin. We also have a newer version in the /dave/work directory.

We type the following which command to show us which version of our program the shell will find and use:

which rf

which rf in a terminal window

The shell reports the version it found is the one in the directory that's in the path.

We type the following to fire it up:

rf

rf in a terminal window

Version 1.0 of rf runs and confirms our expectations were correct. The version found and executed is located in /usr/local/bin.

To run any other version of rf on this computer, we'll have to use the path to the executable on the command line, as shown below:

./work/rf

./work/rf in a terminal window

Now that we've told the shell where to find the version of rf we want to run, it uses version 1.1. If we prefer this version, we can copy it into the /usr/local/bin directory and overwrite the old one.

Let's say we're developing a new version of rf. We'll need to run it frequently as we develop and test it, but we don't want to copy an unreleased development build into the live environment.

Or, perhaps we've downloaded a new version of rf and want to do some verification testing on it before we make it publicly available.

If we add our work directory to the path, we make the shell find our version. And this change will only affect us — others will still use the version of rf in /usr/local/bin .

Add a Directory to Your PATH

You can use the export command to add a directory to the PATH. The directory is then included in the list of file system locations the shell searches. When the shell finds a matching executable, it stops searching, so you want to make sure it searches your directory first, before /usr/local/bin.

This is easy to do. For our example, we type the following to add our directory to the start of the path so it's the first location searched:

export PATH=/home/dave/work:$PATH

export PATH=/home/dave/work:$PATH in a terminal window

This command sets $PATH to be equal to the directory we're adding, /home/dave/work, and then the entire current path.

The first PATH has no dollar sign ($). We set the value for PATH. The final $PATH has a dollar sign because we're referencing the contents stored in the PATH variable. Also, note the colon (:) between the new directory and the $PATH variable name.

Let's see what the path looks like now:

echo $PATH

echo $PATH in a terminal window

Our /home/dave/work directory is added to the start of the path. The colon we provided separates it the rest of the path.

We type the following to verify our version of rf is the first one found:

which rf

which rf in a terminal window

The proof in the pudding is running rf, as shown below:

rf

rf in a terminal window

The shell finds Version 1.1 and executes it from /home/dave/work.

To add our directory to the end of the path, we just move it to the end of the command, like so:

export PATH=$PATH:/home/dave/work

How to Permanently Add Something to PATH

As Beth Brooke-Marciniak said, "Success is fine, but success is fleeting." The moment you close the terminal window, any changes you've made to the $PATH are gone. To make them permanent, you have to put your export command in a configuration file.

When you put the export command in your .bashrc file, it sets the path each time you open a terminal window. Unlike SSH sessions, for which you have to log in, these are called "interactive" sessions.

In the past, you would put the export command in your .profile file to set the path for log in terminal sessions.

However, we found that if we put the export command in either the .bashrc or .profile files, it correctly set the path for both interactive and log in terminal sessions. Your experience might be different. To handle all eventualities, we'll show you how to do it in both files.

Use the following command in your /home directory to edit the .bashrc file:

gedit .bashrc

gedit .bashrc in a terminal window

The gedit editor opens with the .bashrc file loaded.

The gedit editor with the .bashrc file loaded in i t

Scroll to the bottom of the file, and then add the following export command we used earlier:

export PATH=/home/dave/work:$PATH

Save the file. Next, either close and reopen the terminal window or use the dot command to read the .bashrc file, as follows:

. .bashrcThen, type the following echo command to check the path:

echo $PATH

. .bashrc in a terminal window

This adds the /home/dave/work directory to the start of the path.

The process to add the command to the .profile file is the same. Type the following command:

gedit .profile

gedit .profile in a terminal window

The gedit editor launches with the .profile file loaded.

The gedit editor with the .profile file loaded into it

Add the export command to the bottom of the file, and then save it. Closing and opening a new terminal window is insufficient to force the .profile file to be reread. For the new settings to take effect, you must log out and back in or use the dot command as shown below:

. .profile

Setting the Path for Everyone

To set the path for everyone who uses the system, you can edit the /etc/profile file.

You'll need to use sudo, as follows:

sudo gedit /etc/profile

When the gedit editor launches, add the export command to the bottom of the file.

The gedit editor with the /etc/profile file loaded into it.

Save and close the file. The changes will take effect for others the next time they log in.

A Note on Security

Make sure you don't accidentally add a leading colon ":" to the path, as shown below.

echo $PATH in a terminal window

If you do, this will search the current directory first, which introduces a security risk. Say you downloaded an archive file and unzipped it into a directory. You look at the files and see another zipped file. You call unzip once more to extract that archive.

If the first archive contained an executable file called unzip that was a malicious executable, you'd accidentally fire up that one instead of the real unzip executable. This would happen because the shell would look in the current directory first.

So, always be careful when you type your export commands. Use echo $PATH to review them and make sure they are the way you want them to be.

Linux Commands

Files

tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc · tr

Processes

alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap

Networking

netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld