Relative Symlinks for Removable Media/Devices

Symlinks can be a useful and sometimes necessary part of working on the command line. They're often used with absolute paths, extending from either root directories or your user folder. If you're working on a removable disk, however, absolute paths might change depending on which user has the disk mounted. In this case, using relative paths for you symlinks is a great way to ensure they work regardless of who mounts them. Here's a look at how this can be done.

If you've ever used removable devices across multiple user profiles, you might have noticed that, once mounted, the path to the drive changes depending on user. Here's a quick example: suppose I have two users/profiles on a computer and one removable disk named "Extras". For each user, once the disk is mounted, the path to the disk would vary--like this:

/* For Ubuntu-flavored distros, at least (all I ever really use), removable drives should be found in
in the /media/user folder */ 
/media/UserA/Extras
/media/UserB/Extras  

This poses a problem if I ever decide to create symbolic links (symlinks) on a shared disk--at least, if I set the links up with absolute paths. If I use relative paths in my symlinks, though, it shouldn't really matter which user mounts the disk--the links will stay intact. The key to using relative paths in symlinks is knowing where you are. Once you know, both your link destination and your link can be given a path relative to that directory.

Let's start, though, with the basic format for a symlink. The basic pattern should look like this:

$ ln -s <PATH TO LINK DESTINATION> <PATH TO LINK> 

Now let's look at how we can make these paths relative.

Lay of the Land

  • Let's say that I'm in the following directory: /media/terracoders/Extras/Folder A/Bar
  • Let's also say that I want to create a symlink in this same directory--to keep things semantically entertaining, I'll call the link foobar.
  • I want my symlink to point to another directory: /media/terracoders/Extras/Folder B/Foo

In this case, I'd first need to determine a path to Foo relative to Bar. To get to Foo from Bar we would first have to go back two directories--i.e., ../... That means that a relative path to Foo would look like this:

/* Don't forget you'll need to escape spaces in a path when on the command line */ 
../../Extras/Folder\ B/Foo

If I'd like my link to reside in Bar, I'll also need to determine a path to that link relative to Bar. That path would look like this:

/* The leading dot indicates the "current directory" */ 
./foobar

So, now that we've got relative paths to both the link destination and the symbolic link itself, we can piece together a symlink that will work no matter where it gets mounted. In this section, let's look at three things: (again) the proper format for a symlink; what the symlink would look like with absolute paths; and, what the symlink looks like now that we have relative paths:

/* Remember, here's how we format our symlinks*/
$ ln -s <PATH TO DESTINATION> <PATH TO LINK>
/* So, here's how I might create the symlink with absolute paths. 
I can create this link from any directory on my computer; it doesn't matter
because the paths are absolute. This is NO GOOD for removable media */
$ ln -s /media/terracoders/Extras/Folder\ B/Foo /media/terracoders/Extras/Folder\ A/Bar/foobar 

/* Now let's look at the same symlink with relative paths. 
In order for this to work I need to be in a specific place. I start
by finding my way to where I want to be */  
$ cd /media/terracoders/Extras/Folder\ A/Bar 

// Then, I formulate the symlink relative to that place
$ ln -s ../../Folder\ B/Foo ./foobar 

This should do the trick! With the relative paths, you should find that the symbolic links work whatever the user profile, wherever mounted (disk permissions aside...). You can check your symlinks by running ll or ls -l in whichever directory it resides; if properly set up, as in the screen grab below, the output should show you exactly where the symlink points to.

creating a relative symlink on the command-line
Symlinks rock! Escaping spaces is a pain in the but, though.

Here are the contents of Foo:

a symbolic link destination folder
Don't they!?

And here are the contents of my symlink foobar:

symbolic link success
Success!

Not only are relative paths in your symlinks helpful for removable disks, they also have the potential to save you keystrokes. For anyone who spends a lot of time on the command line, that's worth something! Symlinks with relative paths also stand a better chance of staying intact if any of the directory names relative to them (particularly upstream) are ever changed. That's not an absolute, of course, but it's a possibility.