= What's the difference between an absolute path and a relative path?

In both computer programming, web development, and Linux system administration, a directory or file "path" is an important way to identify the location of data on a system.
Programmers often use paths to point to an important coding library, while web developers sometimes point to a graphic or video on the server hosting the site they're creating, and Linux sysadmins might point to an important configuration file.
A path is like a treasure map, describing the layout of a system so that a user or a computer can retrace the steps to retrieve vital data.

== How to read a path

A path describes location.
For instance, `/home/tux/example.txt` tells you to start at the `/home` directory on your hard drive, and then to click into the `tux` directory, where you'll find a text file called `example.txt`.
If it helps, you can say "which contains" between each item in the path as you read it, because every item in a path is something "inside" something else.
In this example, the statement "Start in home, which contains tux, which contains example.txt" is an accurate description of where `example.txt` is located.


== Absolute path

An absolute path makes no assumptions about your current location in relation to the location of the file or directory it's describing.
An absolute path _always_ begins from the absolute start of your hard drive, and describes every step through the file system you must make in order to end up at the target location.

For instance, suppose you're writing a note to your work colleague.
In the note, you write "Push the button every 108 minutes."
Without telling your colleague where the button is located, these instructions are useless, so you change the instruction: "Push /usr/share/widgets/button every 108 minutes."

Now your colleague knows exactly where to locate the button, and the path to the button is the same regardless of whether you or your colleague are following the path.
From your home directory, the button is located in `/usr/share/widgets/button` and from your colleague's home directory, the button is also located in `/usr/share/widgets/button`.

The reason the path is the same no matter what is that the instructions you've provided always start from the farthest region of the file system.
You can't go farther back than `/` so once you're there, you can find `usr`, which contains `share`, which contains `widgets`, which contains the button.

You can always get the absolute path of a file with the `realpath` command:

[source,bash]
----
$ cd /usr/share/aclocal
$ realpath pkg.m4
/usr/share/aclocal/pkg.m4`
$ cd ~
$ realpath example.txt
/home/tux/example.txt
----

== Relative path

Absolute paths are useful, but they're not always efficient.
If you know where the `widgets` directory, which contains `button`, is located. then you don't necessarily have to go all the way back to `/` and then `usr` and then `share` and so on.
Think of it this way: When you stop at a diner on your way to work, you don't have to go all the way back home to resume your journey to the office.
You just step outside the diner and continue on your way, because you know where your office is _relative_ to your current location.

Relative paths use the same principle.
If you're in `/var/log/glusterfs` and you want to view a file in `/var/log/example`, there's no reas to "travel" all the way back to `/var`.
Instead, you can use a relative path to travel out of `audit` and into `example`.

[source,bash]
----
$ sudo cat ../example/file.txt
----

Two dots (`..`) represent moving to a parent directory, so `../example/file.txt` means to move up one directory, and then descend into `example`, which contains `file.txt`.

You may notice that using `..` isn't very descriptive.
That's both the advantage and disadvantage of a relative path.
It's an advantage because it can be quicker to type, but also because it's flexible.
The statement `../example/file.txt` doesn't care what comes before `example`, it only knows that the `example` directory contains a file called `file.txt`.
That makes it equally true whether a user has installed `example` directory to `/var/log` or to `/opt/log` or `/home/tux/.var/log` or any other location. 

Relative paths allow applications and scripts to be largely self-contained.
As long as the immediate environment is predictable, you can always reference files from a known location.
I often use this trick myself in Git repositories.
I know that no matter where the folder is, the top-level directory is always in a known or discoverable state.
Using commands like `git rev-parse --show-toplevel` allows me to use symlinks and scripts that only ever start of my repository rather than the start of the entire hard drive.

=== Single dot

It may seem odd at first, but relative paths also make an allowance for making _no movement_ in a path.
You may have sees instructions telling you to execute a script like this:

[source,bash]
----
$ sh ./example.sh
----

The single dot indicates _your current location_.

There's a good reason for this, actually.
Whether you know it or not, your computer has several default paths that it assumes you're referring to every time you run a command.
This default location, usually just called "your path" or "your $PATH", are places your computer looks to find commands you want to run.

Your computer doesn't inherently know that `ls` or `git` are special keyword commands.
It only executes those applications because when it searches `/usr/bin`, it finds files called `ls` and `git` there.
Imagine what would happen, then, were I to name a file `ls` and then set my computer to run the first file it found with that name.
Any time I was in a directory containing an arbitrary file called `ls`, my computer would attempt to run it, and instead of getting a list of all my files, I'd get whatever `ls` told the computer to do.

That's dangerous, so Linux by default doesn't search arbitrary locations for commands.
Instead, you must specify the location of a file you want to run as an application, even when that file is literally right next to you.

== Other path notation

I'm using the slash ('/') symbol because Linux and the Internet and many others use a slash as a path separator.
While a slash is probably the most common separator, it's not the only one.
Windows systems historically used the backslash ('\') as path separator, although modern Windows systems actually understand both equally.

Many programming languages use path expressions to describe the inheritance of code libraries.
For instance, you might see a Python script referencing `time.sleep()` or `QtWidgets.QVBoxLayout()`.
In these cases, dot separators indicate a kind of path.
The `time` module contains the `sleep` function, and the `QtWidgets` module contains the QVBoxLayout` function.
You may not interact with these paths in the same way, but they are communicating the same concept.
They are mapping the location of a resource, and ensuring that a programmer or a program can locate that resource reliably.

In fact, when an application fails to run on a computer, it's often due to a missing library.
That means that the computer followed a path, and found that there was no library in the place described.
The simple fix is often installing the missing dependency, which places the required library in the expected path.

== Using paths

A path is a map, and like a treasure map a file path can be intended for yourself (the person who buried the treasure in the first place) or for someone else (someone you want to share the treasure with.)
Unlike a treasure map pointing to a single buried treasure, though, a file path can point to data that exists on lots of people's computers.
Be mindful of how you describe the location of an important resource, and when possible use installers like https://opensource.com/article/19/7/introduction-gnu-autotools[Autotools] or https://opensource.com/article/21/5/cmake[CMake] to ensure that your scripts and applications can adapt to different installation preferences.

If you're still coming to grips with paths, remember that practise makes perfect.
The more you use a terminal for navigation around your system, the quicker file system paths feel natural.
