An Introduction to the Command-Line (on Unix-like systems)

by Oliver; 2014

17. The PATH

The most important global variable of all is the PATH. This is the PATH, as distinct from a path, a term we've already learned referring to a location in the filesystem. The PATH is a colon-delimited list of directories where unix will look for executable programs when you enter something on command line. If your program is in one of these directories, you can run it from any location by simply entering its name. If the program is not in one of these directories, you can still run it, of course, but you'll have to include its path.

Let's revisit the idea of a command in unix. What's a command? It's nothing more than a program sitting in a directory somewhere. So, if ls is a program [1], where is it? Use the command which to see its path:
$ which ls  # on my work computer
/bin/ls
$ which ls  # on my home Mac
/usr/local/Cellar/coreutils/8.20/libexec/gnubin/ls
For the sake of argument, let's say I download an updated version of the ls command, and then type ls in my terminal. What will happen—will the old ls or the new ls execute? The PATH comes into play here because it also determines priority. When you enter a command, unix will look for it in each directory of the PATH, from first to last, and execute the first instance it finds. For example, if:
PATH=/bin/dir1:/bin/dir2:/bin/dir3
and there's a command named ls in both /bin/dir1 and /bin/dir2, the one in /bin/dir1 will be executed.

Let's see what your PATH looks like. Enter:
$ echo $PATH
For example, here's a screenshot of the default PATH on Ubuntu:

image

To emphasize the point again, all the programs in the directories specified by your PATH are all the programs that you can access on the command line by simply typing their names.

The PATH is not immutable. You can set it to be anything you want, but in practice you'll want to augment, rather than overwrite, it. By default, it contains directories where unix expects executables, like:
  • /bin
  • /usr/bin
  • /usr/local/bin
Let's say you have just written the command /mydir/newcommand. If you're not going to use the command very often, you can invoke it using its full path every time you need it:
$ /mydir/newcommand
However, if you're going to be using it frequently, you can just add /mydir to the PATH and then invoke the command by name:
$ PATH=/mydir:$PATH  # add /mydir to the front of PATH - highest priority
$ PATH=$PATH:/mydir  # add /mydir to the back of PATH - lowest priority
$ newcommand         # now invoking newcommand is this easy
This is a frequent chore in unix. If you download some new program, you will often find yourself updating the PATH to include the directory containing its binaries. How can we avoid having to do this every time we open the terminal for a new session? We'll discuss this below when we learn about .bashrc.

If you want to shoot yourself in the foot, you can vaporize the PATH:
$ unset PATH  # not advisable
$ ls          # now ls is not found
-bash: ls: No such file or directory
but this is not advisable, save as a one-time educational experience.



[1] In fact, if you want to view the source code (written in the C programming language) of ls and other members of the coreutils, you can download it at ftp.gnu.org/gnu/coreutils. E.g., get and untar the latest version as of this writing:
$ wget ftp://ftp.gnu.org/gnu/coreutils/coreutils-8.9.tar.xz
$ tar -xvf coreutils-8.9.tar.xz
or use git:
$ git clone git://git.sv.gnu.org/coreutils 

<PREV   NEXT>