The Search Path
It may happen that you know there is a program by a particular name on the
system, but when you try to start it from the command line,
you are told that
the file is not found. Because you just ran it yesterday, you assume it has
gotten removed or you don’t remember the correct spelling.
The most common reason for this is that the program you want to start is not
in your search path. Your search path is a predefined set of directories in
which the system looks for the program you type in from the command line
(or is started by some other command). This saves time because the system does not have
to look through every directory trying to find the program. Unfortunately, if
the program is not in one of the directories specified in your path, the system
cannot start the program unless you explicitly tell it where to look. To do
this, you must specify either the full path
of the command or a path relative to where you are currently located.
Lets look at this issue for a minute. Think back to our discussion of files
and directories. I mentioned that every file on the system can be referred to by
a unique combination of path and file name. This applies to executable programs
as well. By inputting the complete path, you can run any program, whether it is
in your path or not.
Let’s take a program that is in everyones path, like date (at least it should
be). The date program resides in the /bin directory, so its full path
is /bin/date. If you wanted to run it, you could type in /bin/date, press Enter and you might get something that looks like this:
Sat Jan 28 16:51:36 PST 1995
However, because date is in your search path,
you need to input only its name, without the path, to get it to run.
One problem that regularly crops up for users coming from a DOS
environment is that the only place Linux
looks for commands is in your path.
However, even if not specified in your path, the first place DOS
looks is in
your current directory. This is not so for Linux.
Linux only looks in your path.
For most users, this is not a problem as the current directory is included
in your path by default. Therefore, the shell
will still be able to execute
something in your current directory. The root user typically does not have the current directory in
its path. In fact, this is the way it should be. If you want to include the
current directory in roots path, make sure it is the last entry in the path so
that all “real” commands are executed before any other command that a user might
try to “force” on you. In fact, I suggest that every user adds entries to the
end of their path.
Assume a malicious user created a “bad” program in his/her directory called
more. If root were to run more in that user’s directory, it could have
potentially disastrous results. (Note that the current directory normally always
appears at the end of the search path. So, even if there was a program called
more in the current directory, the one in /bin would probably get executed
first. However, you can see how this could cause problems for root.) To figure
out exactly which program is actually being run, you can use the (what else?)
which command.
Newer versions of the bash-Shell can be configured to not only complete commands
automatically by inputting just part of the command, but also arguments to the
command, as well as directory names. This is done by pressing the TAB key.
See the bash man-page for more details.
Commands can also be starting by including a directory path, whether or not they are in you
search path. You can use relative or absolute paths, usually with the same result. Details on
this can be found in the section on directory paths.
One very important
environment
variable is the PATH variable. Remember that the PATH tells the
shell where it needs to look when determining what command it should run. One
of the things the shell does to make sense of your command is to find out
exactly what program you mean. This is done by looking for the program in the
places specified by your PATH
variable.
Although it is more accurate to say that the shell
looks in the directories specified by your PATH environment
variable, it is commonly said that the shell
“searches your path.” Because this is easier to type, I am going to use that convention.
If you were to specify a path in the command name, the shell
does not use your PATH variable
to do any searching. That is, if you issued the command bin/date, the
shell would interpret that to
mean that you wanted to execute the command date that was in the bin
subdirectory of your current
directory. If you were in / (the root directory), all would be well and it
would effectively execute /bin/date. If you were somewhere else, the
shell might not be able to find a match.
If you do not specify any path (that is, the command does not contain any
slashes), the system will search through your path. If it finds the command,
great. If not, you get a message saying the command was not found.
Let’s take a closer look at how this works by looking at my path
variable. From the command line,
if I type
echo $PATH
I get
/usr/local/bin:/bin:/usr/bin:/usr/X11/bin:/home/jimmo/bin:/:.
WATCH THE DOT!
If I type in date, the first place in which the shell
looks is the /bin directory. Because that’s
where date resides, it is executed as /bin/date. If I type in
vi, the
shell looks in /bin, doesn’t
find it, then looks in /usr/bin, where it does find vi. Now I type in getdev.
(This is a program I wrote to translate major device numbers into the driver
name. Don’t worry if you don’t know what a major number is. You will shortly.) The
shell looks in /usr/local/bin and doesn’t find it. It then
looks in /bin. Still not there. It then tries /usr/bin and /usr/X11/bin and
still can’t find it. When it finally gets to /home/jimmo/bin, it finds the getdev
command and executes it. (Note that because I wrote this program, you probably
won’t have it on your system.)
What would happen if I had not yet copied the program into my personal bin
directory? Well, if the getdev program is in my current directory, the
shell finds a match with the last “.” in my path.
(Remember that the “.” is translated into the current directory, so the program
is executed as ./getdev.) If that final “.” was missing or the getdev program
was somewhere else, the shell could
not find it and would tell me so with something like
getdev: not found
One convention that I (as well as most other authors) will use with is that commands
that we talk about will be in your path unless we specifically say
otherwise. Therefore, to access them, all you need to do is input the name of
the command without the full path.
Note that the search path is not static, you can add directories to it an any time. In fact it is common that the system will define a default search path for all users and then the users will expand in by adding directories in the .profile. For example, to add a personal bin directory the command might look like this:
PATH=$PATH:$HOME/bin
Keep in mind that the shell will expand all variables before executing the command. Therefore, in this example, $PATH and $HOME are expanded before the shell assigns it to PATH.