What Exactly is Your Shell PATH?

Jalen Davenport
May 4, 2018 · 7 min read

I was recently attempting to explain to a friend what the PATH variable on his computer is used for. After writing up a nice long message in the Slack group we were conversing in, I realized it was good material for a blog post. So here goes…

You’ve probably heard people and/or blog posts talking about editing your PATH or “such-and-such” not being present in your PATH. And you’re just like, “Wait, what exactly is the PATH?”. Good question!

The PATH variable is basically a list of directories your computer looks through to find a requested executable.

If that definition doesn’t make a whole lot of sense at this point, read on and I’ll explain how it all works in-depth…

your PATH is pretty much a bunch of directional signs telling your computer where to go

A BRIEF INTRODUCTION TO THE FILE SYSTEM

Let’s start at square 1️⃣. Your computer is comprised of files; of which there are two types. You’ve got data files (files that just contain information) and you’ve got executable files (files that are used to perform various functions and operations on your computer).

Whenever you open a computer application, you’re in essence just running its executable file(s). The same goes for commands you use in your Terminal — for example, cd and ls are just executable files. These executable files are usually stored in some specific directories. The executable files for your applications, for example, are stored in your Applications folder. Executable files for all your CLI programs/commands are typically stored in one of several places:

  • /binuser utilities — contains some common executables used to navigate directories and manage files via the command line (cd, ls, rm, etc)
  • /sbinsystem programs and administration utilities — contains executables that handle things like booting, restoring, recovering, and/or repairing the system (launchd, reboot, mount, etc)
  • /usr/bincommon utilities, programming tools, and applications — contains executables that aren’t vital to the system’s functionality but are still included in the operating system (ssh, php, vim, etc)
  • /usr/sbinsystem daemons & system utilities — contains executables that are generally run as background processes ( cron, php-fpm, coreaudiod, etc)
  • /usr/local/bin, /usr/local/sbinuser-installed executables, libraries, etc. — contains executables that unlike the above folders aren’t included by default with the operating system (custom shell scripts, and programs installed via Homebrew, utilities installed with and needed by certain GUI programs, etc.)

In addition to these standard directories, some programs use their own
/bin-like directories for storing executable files. For example, Homebrew, a popular package manager for macOS, puts any executable files it installs in /usr/local/Cellar (and those executable files are then symlinked into your /usr/local/bin folder for ease-of-use). Composer, a dependency manager for PHP, installs executable files in ~/.composer/vendor/bin. Depending on how you install MYSQL, some of its utilities (mysqldump for example) are installed in /usr/local/mysql/bin.

ALL ABOUT THE PATH

So, we’ve now get executable files strewn across our file system in these various folders. We can now access and use these executable files in the Terminal by typing out the full absolute path to the file. So, for example, if you wanted to use ls to list out the current directory’s files, you could run
$ /bin/ls in your Terminal. Or if you have an awesome program installed in /usr/local/bin, you could run $ /usr/local/bin/my-program to access it. But do you really want to have to type out the full path to your executable each time? Would you not rather be able to run $ ls or $ my-program?

🤔 Remember: Don’t copy/paste the dollar sign at the beginning of a command! It is used to resemble the prompt in your terminal and it’s just there to let you know that this is command is meant to be run in the terminal.

That’s where PATH comes in! Here’s an analogy of how the PATH works: imagine you’re a manager of several large warehouses. In each of these warehouses you’ve got a bunch of different products. You also have a spreadsheet or a map that lists out the location of each warehouse and what products are being stored at each one.

PATH works in a similar way — it’s a global variable that contains a string of different paths separated by a :. When you type the name of an program without using the absolute path, your computer then uses this variable to understand what directories it should look in to find the executable you’re requesting. Starting with the first directory in the list, it will search for a match to what you requested — which means that directories that comes first in the PATH take precedence over directories later on in the list.

🔥 Tip: If you want to see what your path is currently set to, run $ echo $PATH.

a directory in your PATH = a warehouse 📦

I popped open a Mac with a fresh install of macOS and on that machine the “default” PATH seems to be /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin. So out of the box, your Mac should automatically use the PATH to fulfill requests for any programs installed in the default/standard bin locations. But what if you’re using another tool like Composer or Homebrew and want to add other directories to your PATH?

EDITING YOUR PATH

Since the PATH is essentially just a variable, we can access PATH on the command line or in a script by using $PATH or ${PATH}. The ${PATH} form is particularly helpful when you want to construct something like
$ echo ${PATH}foo, because running $ echo $PATHfoo would try to look for a variable named PATHfoo.

For example, let’s say we want to add a new directory that takes precedence over the currently added directories (i.e. we want to add it in front of the others), we can run the following in our Terminal:

$ export PATH="/my/directory/bin:$PATH"

Now when we run $ echo $PATH you should see your new directory listed before the other directories in the PATH (something like /my/directory/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin).

But maybe you want to add this directory to the end of the PATH so it is the last directory to be searched. Then you could do something like this:

$ export PATH="$PATH:/my/directory/bin"

And your new PATH will look something like /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/my/directory/bin.

Good work! 🎉 You’ve just successfully edited your PATH.

However, the changes you just made to the PATH are not going to persist; in other words, the next time you logout or reboot your Mac, you’ll be back to your original PATH. We want the changes to our PATH to persist, so we’re either going to have to edit the /etc/paths file or add the custom PATH declaration to our local shell files.

If we edit the /etc/paths file, the PATH changes will be applied globally across all the users on the system. If you open /etc/paths in a text editor, you’ll notice there are a bunch of directories listed on individual lines. To add your custom directory, create a new line anywhere in the file and add your directory path (directories higher up in the file take precedence over any directories listed below it). However, if you’re just interested in changing this for your local user, I’d recommend just adding the necessary line(s) to your local shell files.

If you’re using Bash (the default shell on most UNIX systems), you’re probably going to want to add this to either your ~/.bash_profile or your ~/.bashrc file. If you’re using another shell, you can add it to whatever file(s) that shell uses (ZSH for example uses a ~/.zshrc file). Basically, all you need to do is just open the appropriate file in TextEdit or a code editor and somewhere in the file add the custom PATH declaration you need. For example, my ~/.bashrc contains the following lines:

export PATH="/usr/local/bin:/usr/local/sbin:$PATH"
export PATH="$PATH:~/.composer/vendor/bin"

After you’ve added the necessary exports, save the file and quit and relaunch Terminal to load the new changes.

A PRACTICAL EXAMPLE

A common PATH-related issue I hear of all the time is certain applications or tools complaining about not being able to find the mysqldump executable (a database backup utility that is installed with MYSQL). And because it can’t find this executable, it’s getting hung up on whatever task it’s trying to run and spitting out error codes at you. Like I mentioned earlier, MYSQL has it’s own /bin-like directory where utilities like mysqldump are installed.

So what we want to do is add the path to this MYSQL /bin folder to our PATH variable so this tool we’re trying to use will be able to access mysqldump to complete the task. We’re going to opt for editing our shell files because we don’t have a need at the moment to apply this PATH change globally to all the users on the computer. Also, we’re using BASH on this particular computer.

Let’s go ahead and open ~/.bash-profile in a text editor and add the following line:

export PATH="$PATH:/usr/local/mysql/bin"

Next, we’ll need to save the file, close our text editor, and then quit and relaunch Terminal so the new PATH will take effect.

Now we should be able to re-run the task we were trying to complete earlier and it should be able to find mysqldump in the PATH.


Hopefully now you’ve got a pretty good grasp of what your PATH is and how it works!

If you’re having problems with any of the above or still trying to wrap your head around how PATH works, please reach out to me and I’ll try to help you out. You can leave a comment below or reach me on Twitter (@jalendport).

If you found this post helpful or enjoyed the read, please follow me here or on Twitter to see future posts!

Jalen Davenport

Written by

Web Designer & Developer @ Dominion Designs • lover of illustrations, frisbee, coffee, bluegrass music, and Apple devices

More From Medium

Also tagged Linux

Related reads

2.5K

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade