Directory Paths

Directory Paths

As we discussed in the section on the seach path, you can often start programs simply by inputting their name, provided they lie in your search path. You could also start a program by referencing it through a relative path, the path in relation to your current working directory. To understand the syntax of relative paths, we need to track a moment. As I mentioned, you can refer to any file or directory by specifying the path to that directory. Because they have special significance, there is a way of referring to either your current directory or its parent directory. The current directory is referenced by “.” and its parent by “..” (often referred to in conversation as “dot” and “dot-dot”).

Because directories are separated from files and other directories by a /, a file in the current directory could be referenced as ./file_name and a file in the parent directory would be referenced as ../file_name. You can reference the parent of the parent by just tacking on another ../, and then continue on to the root directory if you want. So the file ../../file_name is in a directory two levels up from your current directory. This slash (/) is referred to as a forward slash, as compared to a back-slash (\), which is used in DOS to separate path components.

When interpreting your command line, the shell interprets everything up to the last / as a directory name. If we were in the root (upper-most) directory, we could access date in one of several ways. The first two, date and /bin/date, we already know about. Knowing that ./ refers to the current directory means that we could also get to it like this: ./bin/date. This is saying relative to our current directory (./), look in the bin subdirectory for the command date. If we were in the /bin directory, we could start the command like this: ./date. This is useful when the command you want to execute is in your current directory, but the directory is not in your path. (More on this in a moment.)

We can also get the same results from the root directory by starting the command like this: bin/date. If there is a ./ at the beginning, it knows that everything is relative to the current directory. If the command contains only a /, the system knows that everything is relative to the root directory. If no slash is at the beginning, the system searches until it gets to the end of the command or encounters a slash whichever comes first. If there is a slash there (as in our example), it translates this to be a subdirectory of the current directory. So executing the command bin/date is translated the same as ./bin/date.

Let’s now assume that we are in our home directory, /home/jimmo (for example). We can obviously access the date command simply as date because it’s in our path. However, to access it by a relative path, we could say ../../bin/date. The first ../ moves up one level into /home. The second ../ moves up another level to /. From there, we look in the subdirectory bin for the command date. Keep in mind that throughout this whole process, our current directory does not change. We are still in /home/jimmo.

Searching your path is only done for commands. If we were to enter vi file_name (vi is a text editor) and there was no file called file_name in the current directory, vi would start editing a new file. If we had a subdirectory called text where file_name was, we would have to access it either as vi ./text/file_name or vi text/file_name. Of course, we could access it with the absolute path of vi /home/jimmo/text/file_name.

When you input the path yourself (either a command or a file) The shell interprets each component of a pathname before passing it to the appropriate command. This allows you to come up with some pretty convoluted pathnames if you so choose. For example:

cd /home/jimmo/data/../bin/../../chuck/letters

This example would be interpreted as first changing into the directory /home/jimmo/data/, moving back up to the parent directory (..), then into the subdirectory bin, back into the parent and its parent (../../) and then into the subdirectory chuck/letters. Although this is a pretty contrived example, I know many software packages that rely on relative paths and end up with directory references similar to this example.

Current directory Target directory Relative path Absolute path
/data/home/jimmo/letter /data/home/jimmo/letter/dave ./dave or dave /data/home/jimmo/letter/dave
/data/home/jimmo/letter /data/home/jimmo ../ /data/home/jimmo
/data/home/jimmo/letter /data/home/ ../.. /data/home
/data/home/jimmo/letter /tmp ../../../../tmp /tmp