How to Use Symbolic Links (Symlinks) on Linux

On Linux, we will sometimes encounter files like these:

They are called symbolic links, symlinks, or soft links.

A symbolic link is a sort of shortcut. A file that points to another file, or directory.

In the screenshot above we can see an arrow ->. Which shows us that the soft link called htmlfiles points to the /var/www/html directory. Whenever we access the htmlfiles symbolic link we are redirected to the real directory at /var/www/html.

To create a symbolic link (symlink / soft link) on Linux (or even MacOS), all we need to do is run the ln command.

The syntax of the ln command, to create a symbolic link, is:

ln -s TARGET_file_or_directory NAME_of_symbolic_link

-s is what tells the ln command to create a symbolic link.

Example of a real command:

ln -s /var/www/html my_symbolic_link

This would create a symbolic link that points to the /var/www/html directory. And it would name the link my_symbolic_link.

To remember the syntax, we can think like this: First we specify the destination of our symlink; what it will point to. Then we specify the name of our symbolic link.

💡
It's important to add -s, otherwise ln would create a hard link instead of a soft link / symbolic link.

Now let's see some specific examples on how to use the ln command, and how the symbolic link behaves when it's accessed.

Imagine we often need to access the /var/www/html directory, to update our website. And we're sick and tired to manually navigate to it; type all those parts: "var, www, html".

To make this easier, we can create a symbolic link that points to /var/www/html. And we can call the link htmlfiles:

ln -s /var/www/html htmlfiles

That's if we want to create the symbolic link in our current directory.

If we want to create it somewhere else – like in the /home/alex/ directory – then we just specify the full path to this directory, and type the name of our symbolic link at the end:

ln -s /var/www/html /home/alex/htmlfiles

Either way, now we have this symbolic link called htmlfiles:

And when we access it we are redirected to /var/www/html.

For example, if we use ls commands to list the contents in the htmlfiles "directory" and then the /var/www/html directory, this is what we get:

The same content appears because htmlfiles redirects us to /var/www/html.

  • Running ls htmlfiles
  • Is the same as running ls /var/www/html/

But here's something weirder.

Let's create a symbolic link that points to the /home/alex directory, and call the link fakedir.

ln -s /home/alex /tmp/fakedir

What if we switch to this symbolic link, with the cd command?

cd /tmp/fakedir

Interesting. Our command prompt shows us that we are inside a directory called /tmp/fakedir. Which is actually... a lie! 🙂

The truth is that we are inside /home/alex at this point. If we run the ls command we will see Alex's personal files:

ls

And to prove that the command prompt is "lying" to us, we can use the realpath command. One way is to ask realpath "What is the current directory?" The . in the next command represents "current directory".

realpath .

And we can see where we actually are: /home/alex. But it's interesting to see how symbolic links work like in this scenario, when they point to directories.

There might be cases where we switch to what we think is a real directory, but it's actually a symbolic link pointing to a different location.

To create a symbolic link pointing to the /var/www/html/index.nginx-debian.html file and call the symbolic link index.html, we can run a command like this:

ln -s /var/www/html/index.nginx-debian.html index.html

That's if we want to create the symbolic link called index.html in our current directory. If we want to create it at another location, like /home/alex/, then we need to specify the full path for the symbolic link:

ln -s /var/www/html/index.nginx-debian.html /home/alex/index.html

Either way, we now have our symbolic link called index.html:

If we try to read our index.html file, we'll see this:

And if we try to read /var/www/html/index.nginx-debian.html instead, we'll see the same content.

Which is what we expect, since index.html points to /var/www/html/index.nginx-debian.html.

But note how much easier it is to type:

  • cat index.html
  • Rather than cat /var/www/html/index.nginx-debian.html.

Up to this point we used absolute paths. For example, we made a soft link called htmlfiles point to the absolute path of this directory: /var/www/html.

But there are scenarios where it's useful to make a symbolic link point to a relative path instead. Take this command as an example:

ln -s libraries/libapp.so.3.2.2 libapp.so

This would create a soft link called libapp.so; but note it does not point to an absolute path anymore. Instead, it points to a relative path: libraries/libapp.so.3.2.2.

This relative path is like saying:

Hey, if someone accesses this soft link called libapp.so this is what you do. You descend into a directory called libraries. And then redirect to the libapp.so.3.2.2 file from this subdirectory.

We can also use a relative path that goes one directory up:

ln -s ../libapp.so.3.2.2 libapp.so

Here, the two dots .. represent one directory up. If someone tries to access the soft link called libapp.so then they will be redirected one directory up, and then to the libapp.so.3.2.2 file from that directory above.

Relative paths can get complex, like two directories up, or more:

ln -s ../../libapp.so.3.2.2 libapp.so

We just used the .. thing twice to go two directories up.

Of course, we can also go two subdirectories down, or more:

ln -s additional/libraries/libapp.so.3.2.2 libapp.so

Here, we tell the soft link to first descend into a subdirectory called additional and then into the next subdirectory here called libraries, and finally point to the libapp.so.3.2.2 file.

Imagine we do this in a directory containing a software project. The nice thing with relative paths is that now these soft links / symbolic links will work even if we move the software directory around.

For example, if we move it from /home/alex/project to /home/john/project. With relative paths, symbolic links will still work. Since libapp.so points to a subdirectory called libraries in this big project directory. libraries will always be there, one directory down, in the project directory.

But what if we use absolute paths, and point a symbolic link to something like /home/alex/project/libraries/libapp.so.3.2.2? In this case, when we move theproject directory to /home/john, the symbolic link will become broken. Because it will still point to /home/alex, and the software project was moved to /home/john.

To remove a symbolic link we just use the rm command:

rm name_of_symlink_file

For example, to remove our symbolic link called htmlfiles we would run:

rm htmlfiles

That's if htmlfiles is in our current directory. If it's in another location, like /home/alex/, we just specify the full path to the symbolic link file:

rm /home/alex/htmlfiles
But won't this remove the target of that symlink? If symlink A points to file B, when I remove A, won't it delete B?

No, the rm command looks at the symbolic link as just any other file. So when we tell it to remove a symlink, it just removes that symlink, NOT the target that it points to.

A ls command might highlight symbolic links with a special color:

Note how the two symbolic links we created are highlighted with the cyan (blue-ish) color here. But a regular file is shown with a simple white color.

This kind of highlight depends on how the Linux operating system is configured. It might not show up like this on every system. So we need a more reliable way.

One way to tell ls to always show us what might be a symbolic link (and where it leads to) is to add the -l option for the long listing format:

ls -l

Now we can see that the symbolic link called htmlfiles points to the /var/www/html directory. Whenever ls -l displays a symbolic link it will have that -> arrow showing where it leads to.

Another hint that something is a symbolic link is the l letter. The one that shows as the first letter in a ls -l command.

And if we want to inspect just a single symbolic link and see what it points to, we can use the realpath command. For example, to see what htmlfiles points to here:

realpath htmlfiles

Or, if we need to use an absolute path to this symlink:

realpath /home/alex/htmlfiles

Symbolic links don't have rules set in stone on why we might use them, or need them. It's up to each user to find a specific use-case. But here are some common reasons to use symlinks.

Imagine that we often need to work with this file: /var/www/html/index.nginx-debian.html. Here's a command we'd need to run just to view this file:

cat /var/www/html/index.nginx-debian.html

If it's a one time thing, no problem. But what if we'd need to run this 50 times just today? Typing the path to that file can become tiring. One solution? Just create a symlink to it:

ln -s /var/www/html/index.nginx-debian.html index.html

Now, in our own personal directory, we have this index.html file:

And index.html points to /var/www/html/index.nginx-debian.html. Meaning that to read it, instead of typing the long command:

cat /var/www/html/index.nginx-debian.html

We can just use our symlink and type a much shorter command:

cat index.html

And just like that we get access to the same target file in /var/www/html/index.nginx-debian.html.

Why do we need symbolic links?

To Get Convenient Access to Often-Used Files or Directories

If we often need to navigate to a complicated directory path like /some/directory/path/here, we can just create a symlink in our home directory. And then we just refer to the symbolic link, which is faster to type, and we'll be redirected to the "distant" directory that exists somewhere else.

Example:

A lot to type. But we symlink to it with:

ln -s /sys/bus/hid/devices/0003:0627:0001.0001/driver/module/sections/ sections

Now we can view this directory with a much shorter command, by just using our symbolic link called sections:

ls sections

Even the screenshot of this command is now a lot smaller 🙂.

Same benefit if we symlink to a file with a long path.

To Have Access to the Same Thing from Multiple Locations

Imagine two user accounts on a computer: John, and Jane. And a directory like /storage/family/photos. Both of our users want to easily access these family photos.

Instead of copying the photos to each of their home directories, we could just create symlinks. Something like /home/john/family_photos and /home/jane/family_photos. Where family_photos are two symbolic links, and they point to the real location of the photos, /storage/family/photos. So we'd get something like this:

  • /home/john/family_photos -> /storage/family/photos
  • /home/jane/family_photos -> /storage/family/photos

Both users can access this directory as if it would be part of their own home directory (even though it exists in an external location).

To Trick Applications into Thinking They're Accessing a Certain File, but Redirecting them to Another

A typical use-case: A program needs a library file called libapp.so. But libapp.so is a new version of that library, and it doesn't work with this program. It needs the older library.

We can just create a symbolic link, call it libapp.so, but make it point to libapp.so.3.2.2, the older version which works. So the app thinks it's accessing libapp.so, but that's just a symbolic link that redirects it to libapp.so.3.2.2. Problem solved.

To Redirect Deprecated Commands (Which No Longer Exist) to the New Commands

For example, the poweroff command was removed on many Linux systems. But most users have a habit of running poweroff to turn off their servers.

Instead of throwing a "Command not found error" this will work. Because poweroff is a symbolic link that points to the systemctl command. And when we run poweroff, we're actually redirected to systemctl, which will take care of powering off the system.

Other use cases are possible with symbolic links. As mentioned, it all depends on user-specific needs.

Hope you enjoyed this blog. And if you want to learn more about Linux, check out our course which cover Ubuntu:

Linux Foundation Certified System Administrator (LFCS) | KodeKloud
Prepare for the Linux Foundation Certified System Administrator (LFCS) Exam

Or this one, that covers Red Hat Enterprise Linux (RHEL):

Red Hat Certified System Administrator(RHCSA) | KodeKloud

See you in the next blog!