Navigating the filesystem with relative paths at the command line

Learn the difference between absolute and relative paths and how to use them, and save yourself a lot of time and potential trouble.
Register or Login to like
5 tools to support distributed sysadmin teams

If you’re on your way to work, but you stop by a deli for breakfast first, you don’t go back home after breakfast so you can restart your journey. Instead, you continue from where you are because you understand where your office is located relative to your current location. Navigating your computer is the same way. If you change your working directory in a terminal to a subdirectory, such as Pictures, you don’t necessarily have to go home again just to make your way into Documents. Instead, you use a relative path.

Conversely, absolute paths always begin from the start of your hard drive. You know that you’ve reached the start by a lone forward slash (/) with nothing to its left, because your drive’s root level is the biggest container, holding all your folders and files within it. For that reason, the path /home/seth (and its shorthand version ~, although that’s less clear, because it lacks the leftmost slash) is considered an absolute path. It represents your hard drive’s base level, which contains the home directory, which in turn contains seth (my username).

Anything starting with a forward slash is an absolute path, which is the digital equivalent of you going 12 blocks back home just to reach a location that’s two blocks away from where you are now. That fact doesn’t mean absolute paths are bad, though. There are many valid reasons to use absolute paths, not the least of which is their clarity. If you can navigate your drive from absolute paths, then use that as a wayfinder. With auto-completion, typing a full path can be as quick as using a relative path, especially with autocompletion.

That said, relative paths can be convenient, and in some cases vital. For instance, you can never be sure of a web server’s absolute path. If a web designer knows they keep web fonts in a local directory and they link to those fonts on their development laptop using the absolute path /home/webdev/Public/, then all of their links break when the code is pushed to /var/www/ on the server.

Besides that, sometimes it really is quicker and easier to type cd ../Documents instead of cd /home/seth/Documents.

Relative paths use two control sequences: the single (.) and the double (..) dot. A single dot means don’t move. The double dot means take one step back. These dots work best when you’re somewhat familiar with what’s on your drive, and provided that you can visualize the corresponding paths.

It may help to visualize each directory as a room in a house. For instance, knowing that you have a home directory that contains both a Pictures and a Documents folder, you can visualize each subdirectory as a step forward from home:

Stepping into a directory.

To get from one room to the other, you must go back to the common area using the step back control sequence, and then step forward into the other. You can get your current location at any time with the pwd (print working directory) command:

$ pwd
$ cd ../Documents
$ pwd

Remember that a single dot means don’t move, and it does exactly that:

$ pwd
$ cd .
$ pwd

It might seem odd to have a special command representing a state of no change, but it’s a usefully explicit directive. For instance, were you to create a custom application to list a directory’s contents and save it in your home directory, foolishly naming the application reboot, then any time you used that custom application you would want to be careful that your computer knew exactly which reboot command to execute.

One way you can specify which version is to provide an explicit path to your custom and poorly named application. The single dot reinforces your desire not to stray from your intended path when you’re already in the directory:

$ pwd
$ ./reboot
Documents/     Downloads/
Music/         Pictures/
Public/        Spheniscidae/
Videos/        Yugolothae/

Another time you might find a need for a single dot specifier is when a tool doesn't look in the current directory for an argument by default. For example, the dnf command assumes that any package you tell it to install is a package you need it to download from a repository. When you want to perform a local install of something you've already downloaded, you can point it to a package in the current directory with a single dot so dnf works with it instead of trying to find it in a repository:

$ sudo dnf install ./example.rpm

Sometimes the single dot can be useful as a filler character in paths that you expect to contain a number of levels. For instance, take a web developer who used several links to a font directory that was once three steps back. Recently, though, this developer moved the font directory into the same directory as their HTML. If the developer doesn’t replace all instances of ../../../fonts with ./././fonts, their site will break.

Note: In the case of this example, changing ../../../fonts to ./fonts would work, but assume for the sake of this example that doing so would break a script that expects to see three levels before the fonts directory.

Relative paths can be confusing at first, so stick to absolute paths when navigating your computer until you’re comfortable with the concept of relativity. Many people find them useful, while others do not use them. It’s all relative.

Seth Kenlon
Seth Kenlon is a UNIX geek, free culture advocate, independent multimedia artist, and D&D nerd. He has worked in the film and computing industry, often at the same time.


I have found in the past that sometimes you need to use ./ to force some command to use the current directory, such as when you have downloaded an RPM outside a repository.
rpm -ivh ./SomeRPM.rpm
dnf install ./SomeRPM.rpm

What about use of `pushd...popd` and `cd -`, for example? These commands may not be directly related to the topic, but may save a lot of time to someone new in shell.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.