What’s a $PATH anyway?
Published August 30, 2016
You’ve probably seen
$PATH or just
PATH before as the place you need to add new commands for your prompt. What is that? Where is it? How does it work?
High Level: What’s the $PATH?
$PATH is a shell variable that holds an ordered list of all the directories that your shell will search within when you tell it to run a command.
Commands, how do they work?
When you run a command like
date in your prompt your shell first looks to see if that command matches any “built-in” commands. If so it will run that built-in command that’s actually part of the shell itself.
If the command doesn’t match a built-in then your shell examines the
$PATH variable to see all the directories that it’s allowed to search in to find a command to run. Starting with the first it checks each directory and when it finds an executable file with a filename matching your command then it will execute it with any arguments you’ve given.
$PATH in action
First open up your prompt.
Great! Now let’s examine what the shell would run for various commands. We can do that with a command called
which. Given a command,
which tells you what the shell would run.
$ which date /bin/date
There we see that if we were to run the
date command, the shell would find and execute
Let’s get meta on it.
# In zsh which is a built-in $ which which # In bash which is an actual command $ which which /usr/bin/which
Let’s try something that might give you some more interesting results.
$ which ruby /Users/sdball/.asdf/shims/ruby
On the machine I’m writing this post on I use the excellent asdf to manage my Ruby installation. When I ask my shell what it would run for
ruby I find that it wouldn’t actually call a specific Ruby version, but this asdf shim. In that way asdf can control which Ruby version it uses depending on the current shell or project settings.
Ok, but what does it do?
You can add your own directories to the $PATH so you can easily add new executable commands to your command line environment! Woo!
The syntax is weird, but the gist is that you want to add your new directories to the
PATH variable without interfering with what’s already there. You do that be declaring the new
PATH variable to be the original
PATH variable plus your own stuff. The directories are each separated with a
What’s on $PATH already?
If you want to see what your
PATH variable already has you can use the
echo command. The
echo command prints all of its arguments to
$ echo $PATH /Users/sdball/bin:/Users/sdball/.asdf/bin:/Users/sdball/.asdf/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
If you want some nicer formatting let’s translate those
: characters into newlines with the
$ echo $PATH | tr : "\n" /Users/sdball/bin /Users/sdball/.asdf/bin /Users/sdball/.asdf/shims /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Your own bin directory
.zshrc or similar shell startup file you can add a line like this:
That says to make
$HOME/bin the first place the shell checks for any command before going on to check whatever was already configured.
I highly recommend having a
bin directory in your home directory in your
PATH variable. That gives you an easy place to place new shell scripts or your own custom commands.
If you’d like to see what I keep in
bin feel free to look! My
bin directory is a public part of my dotfiles repo.
Last modified March 31, 2020 #command line