Have you ever heard about the concept of symbolic link in Linux?
You might have heard the word symlink instead…they are the same thing.
What is a symbolic link?
A symbolic link in Linux (or Unix-like operating systems) is a shortcut to a file or directory. You can use it to simplify the way you access the file or directory if their path is long or difficult to remember. The ln command allows to create symbolic links on a Linux system.
In this article we will play with the ln command to get familiar with the creation of symbolic links on Linux.
Let’s start!
Symbolic Link to a File in Linux
Why would you create a symlink to a file in Linux?
One reason is to refer to files on our Linux system in a more generic way.
For example, I have created the reports directory in which every month an automated script (not part of this tutorial) creates a report of the monthly expenses for my business.
Below you can see the content of the reports directory:
[ec2-user@ip-172-31-1-2 reports]$ ls -ltr
total 0
-rw-rw-r-- 1 ec2-user ec2-user 12 May 1 14:50 report_April2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jun 1 14:50 report_May2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jul 1 14:50 report_June2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Aug 1 14:50 report_July2020
Let’s say I want to have an automated way to access the latest report without knowing its name (that changes from month to month).
I can update the script that generates the monthly report to also create a symlink called last_report that points to the most recent report generated.
In this specific case the script that generates the report for July would also execute the following command:
ln -s report_July2020 last_report
With the ls command we can see the symlink created:
lrwxrwxrwx 1 ec2-user ec2-user 15 Aug 1 14:57 last_report -> report_July2020
In this way I can see the content of the most recent report simply using the command:
cat last_report
What happens when the report for the next month is generated?
Our script has to repoint the symlink from report_July2020 to report_August2020 using the unlink and ln commands:
[ec2-user@ip-172-31-1-2 reports]$ unlink last_report
[ec2-user@ip-172-31-1-2 reports]$ ln -s report_August2020 last_report
[ec2-user@ip-172-31-1-2 reports]$ ls -ltr
total 16
-rw-rw-r-- 1 ec2-user ec2-user 12 May 1 14:50 report_April2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jun 1 14:50 report_May2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jul 1 14:50 report_June2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Aug 1 14:50 report_July2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Sep 1 14:50 report_August2020
lrwxrwxrwx 1 ec2-user ec2-user 17 Sep 1 14:50 last_report -> report_August2020
Makes sense?
Symbolic Link to a Directory in Linux
Let’s see an example of how we can create a symbolic link to a Linux directory.
Create a new directory under /opt/scripts/:
mkdir -p /opt/scripts/this/is/a/complex/path/
You can see that we are passing the -p flag to the mkdir command. This flag is used to create any directories in this path if they don’t exist.
Here is what happens without the -p flag (we replace the directory this with this2):
mkdir /opt/scripts/this2/is/a/complex/path/
mkdir: cannot create directory ‘/opt/scripts/this2/is/a/complex/path/’: No such file or directory
Then we create a file called test.txt under the directory /opt/scripts/this/is/a/complex/path/.
echo "This is our test file" > /opt/scripts/this/is/a/complex/path/test.txt
As you can see we have used the echo command and redirection to create a file that has a single line with the text “This is our test file”.
Now, we want to access this file without having to remember this complex path.
Under /opt/scripts/ we create a symlink called complex_path to the directory in which the file is located.
cd /opt/scripts/
ln -s /opt/scripts/this/is/a/complex/path/ complex_path
The format of the ln command is:
ln -s <source_directory> <target_directory>
Where source_directory is the existing directory and target_directory is the name of the link we are creating.
Here is what we get when we create the complex_path symlink:
[ec2-user@localhost scripts]$ pwd
/opt/scripts
[ec2-user@localhost scripts]$ ls -al complex_path
lrwxrwxrwx 1 ec2-user ec2-user 36 Mar 17 23:54 complex_path -> /opt/scripts/this/is/a/complex/path/
And now let’s cd into the symlinked directory and use pwd to check the working directory:
[ec2-user@localhost scripts]$ cd complex_path/
[ec2-user@localhost complex_path]$ pwd
/opt/scripts/complex_path
As you can see the pwd command shows the logical path for the directory instead of the actual real path of the directory the symlink refers to…
To show the physical path we need to use the -P flag:
[ec2-user@localhost complex_path]$ pwd -P
/opt/scripts/this/is/a/complex/path
If we use ls we can see that in the complex_path directory there is the test.txt file we have created at the beginning:
[ec2-user@localhost complex_path]$ ls -al
total 4
drwxrwxr-x 2 ec2-user ec2-user 22 Mar 18 00:14 .
drwxrwxr-x 3 ec2-user ec2-user 18 Mar 17 23:50 ..
-rw-rw-r-- 1 ec2-user ec2-user 22 Mar 17 23:54 test.txt
Removing a symbolic link
What happens if you don’t need a symbolic link anymore?
You can remove it using the unlink command:
cd /opt/scripts/
unlink complex_path
[ec2-user@localhost scripts]$ ls -al complex_path
ls: cannot access complex_path: No such file or directory
Very often the unlink and ln commands are used together if we want to point a symlink to a different directory.
This is a common scenario when releasing a new version of a software…
Let’s say the current version of your software is under the directory my_software_v1 and you want to have a generic symlink called my_software so you don’t have to remember which version of your software is active.
You will have something like:
lrwxrwxrwx 1 ec2-user ec2-user 14 Mar 18 00:21 my_software -> my_software_v1
drwxrwxr-x 2 ec2-user ec2-user 6 Mar 18 00:21 my_software_v1
It’s time to release v2 of your software, so you create the directory my_software_v2.
[ec2-user@localhost software]$ mkdir my_software_v2
[ec2-user@localhost software]$ ls -al
total 0
drwxrwxr-x 4 ec2-user ec2-user 69 Mar 18 00:23 .
drwxr-xr-x 5 ec2-user ec2-user 185 Mar 18 00:21 ..
lrwxrwxrwx 1 ec2-user ec2-user 14 Mar 18 00:21 my_software -> my_software_v1
drwxrwxr-x 2 ec2-user ec2-user 6 Mar 18 00:21 my_software_v1
drwxrwxr-x 2 ec2-user ec2-user 6 Mar 18 00:23 my_software_v2
Now, how do you repoint the symlink to the new version of your software?
- Unlink the existing symlink
- Re-create the symlink this time pointing to my_software_v2
[ec2-user@localhost software]$ unlink my_software
[ec2-user@localhost software]$ ln -s my_software_v2 my_software
[ec2-user@localhost software]$ ls -al
total 0
drwxrwxr-x 4 ec2-user ec2-user 69 Mar 18 00:25 .
drwxr-xr-x 5 ec2-user ec2-user 185 Mar 18 00:21 ..
lrwxrwxrwx 1 ec2-user ec2-user 14 Mar 18 00:25 my_software -> my_software_v2
drwxrwxr-x 2 ec2-user ec2-user 6 Mar 18 00:21 my_software_v1
drwxrwxr-x 2 ec2-user ec2-user 6 Mar 18 00:23 my_software_v2
In this way you can access the directory of your latest software simply using the my_software symbolic link.
This is a common technique used when you have to release a new version of your software on a Linux server.
How to Link All Files in a Directory with Symbolic Links
A common question is, how to create symlinks for all the files in a directory.
Let’s see how with an example…
I have created the directory firstdir under /var/tmp/ and it contains the following files:
[ec2-user@ip-172-31-1-2 tmp]$ ls -al first_dir/
total 0
drwxrwxr-x 2 ec2-user ec2-user 91 Aug 2 19:12 .
drwxrwxrwt 6 root root 133 Aug 2 19:12 ..
-rw-rw-r-- 1 ec2-user ec2-user 0 Aug 2 19:12 testfile1
-rw-rw-r-- 1 ec2-user ec2-user 0 Aug 2 19:12 testfile2
-rw-rw-r-- 1 ec2-user ec2-user 0 Aug 2 19:12 testfile3
-rw-rw-r-- 1 ec2-user ec2-user 0 Aug 2 19:12 testfile4
-rw-rw-r-- 1 ec2-user ec2-user 0 Aug 2 19:12 testfile5
To create symlinks in the directory /var/tmp/second_dir that point to the files in first_dir execute (from any directory) the following command:
ln -s /var/tmp/first_dir/* /var/tmp/second_dir/
Here’s how the content of second_dir looks like after executing the command:
[ec2-user@ip-172-31-1-2 tmp]$ ls -al second_dir/
total 0
drwxrwxr-x 2 ec2-user ec2-user 91 Aug 2 19:18 .
drwxrwxrwt 6 root root 135 Aug 2 19:17 ..
lrwxrwxrwx 1 ec2-user ec2-user 28 Aug 2 19:18 testfile1 -> /var/tmp/first_dir/testfile1
lrwxrwxrwx 1 ec2-user ec2-user 28 Aug 2 19:18 testfile2 -> /var/tmp/first_dir/testfile2
lrwxrwxrwx 1 ec2-user ec2-user 28 Aug 2 19:18 testfile3 -> /var/tmp/first_dir/testfile3
lrwxrwxrwx 1 ec2-user ec2-user 28 Aug 2 19:18 testfile4 -> /var/tmp/first_dir/testfile4
lrwxrwxrwx 1 ec2-user ec2-user 28 Aug 2 19:18 testfile5 -> /var/tmp/first_dir/testfile5
Make sure you use the absolute path for both directories in the ln command, otherwise you could create symlinks in second_dir that point to an incorrect relative path.
Another option could be to use relative paths in the ln command instead of absolute paths.
Let’s assume that we haven’t created any symlinks in second_dir yet…
Access the second_dir directory using the cd command and execute the following command:
[ec2-user@ip-172-31-1-2 second_dir]$ ln -s ../first_dir/* .
This time we have used relative paths based on the fact that we are in the second_dir directory when we create the symlinks.
The dot ( . ) at the end of the ln -s command tells the command to create the symbolic links in the current directory.
Here’s how the content of second_dir looks like:
[ec2-user@ip-172-31-1-2 second_dir]$ ls -al
total 0
drwxrwxr-x 2 ec2-user ec2-user 91 Aug 2 19:52 .
drwxrwxrwt 6 root root 135 Aug 2 19:17 ..
lrwxrwxrwx 1 ec2-user ec2-user 22 Aug 2 19:52 testfile1 -> ../first_dir/testfile1
lrwxrwxrwx 1 ec2-user ec2-user 22 Aug 2 19:52 testfile2 -> ../first_dir/testfile2
lrwxrwxrwx 1 ec2-user ec2-user 22 Aug 2 19:52 testfile3 -> ../first_dir/testfile3
lrwxrwxrwx 1 ec2-user ec2-user 22 Aug 2 19:52 testfile4 -> ../first_dir/testfile4
lrwxrwxrwx 1 ec2-user ec2-user 22 Aug 2 19:52 testfile5 -> ../first_dir/testfile5
Makes sense?
Conclusion
In this article you have learned how to use the:
- ln command to create a symbolic link to a file or directory in Linux
- echo command to create a new file
- mkdir command to create a nested directory structure
- pwd command to show the physical path of the current directory
- unlink command to remove a symbolic link
You have also learned how to create symbolic links to all the files in a directory!
And you, are you using symbolic links? If yes, how?
Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.
With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for robotics with Raspberry Pi.