In my previous article, I demonstrated how to create a hard link that looks like a unique file but actually points back to another file. A hard link can only point to a file, not a directory, and it doesn't add to the overall index node (inode) count.
[ Keep your most commonly used commands handy with the Linux commands cheat sheet. ]
An inode is a data structure describing a filesystem object, such as a file or a directory. It stores metadata pertaining to that object, including time stamps, block maps, or extended attributes.
You can see inodes in action by creating a directory and then looking at its inode and size information:
$ mkdir dir
$ ls -li
total 0
25606589 drwxrwxr-x. 2 localuser localuser 6 set 19 15:21 dir
$ stat dir
File: dir
Size: 6 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 25606589 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-19 15:21:27.616000000 -0300
Modify: 2022-09-19 15:21:27.616000000 -0300
Change: 2022-09-19 15:21:27.616000000 -0300
Birth: 2022-09-19 15:21:27.616000000 -0300
Use the ls
command with the -i
option to display inodes. You can see that the inode address of the given dir
directory below is 25606589. You can confirm the inode and check other metadata information with the stat
command.
Create a file inside this directory and check the same information:
$ touch dir/file
$ stat dir
File: dir
Size: 18 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 25606589 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-19 15:29:37.495000000 -0300
Modify: 2022-09-19 15:29:40.276000000 -0300
Change: 2022-09-19 15:29:40.276000000 -0300
Birth: 2022-09-19 15:21:27.616000000 -0300
$ ls -li dir/file
25606591 -rw-rw-r--. 1 localuser localuser 0 set 19 15:29 dir/file
$ stat dir/file
File: dir/file
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 25606591 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-19 15:29:40.276000000 -0300
Modify: 2022-09-19 15:29:40.276000000 -0300
Change: 2022-09-19 15:29:40.276000000 -0300
Birth: 2022-09-19 15:29:40.276000000 -0300
The file has its own inode address (25606591), and it's 0 bytes in size because it has no contents. Add just one single byte of data to it and see what happens:
$ echo 1 > dir/file
$ stat dir/file
File: dir/file
Size: 2 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 25606591 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-19 15:29:40.276000000 -0300
Modify: 2022-09-19 15:36:18.812000000 -0300
Change: 2022-09-19 15:36:18.812000000 -0300
Birth: 2022-09-19 15:29:40.276000000 -0300
The file now consumes eight sectors, even though you only added 1B of data. That is because you're working with the default 4KiB block disk size and 512B sector size.
The inode address remains the same, which is important because regardless of the file size, it's always referenced by its inode address, not each individual sector consumed. If you copy the file, though, the copy would get its own inode address, and it would consume another eight sectors. That's significant because you don't make a copy when you create a link.
What are symbolic links?
Unlike hard links, symbolic links (also called "soft" links) are just special files that point to a file or directory in your system. Symbolic links have advantages over hard links in some scenarios, such as creating links for directories, pointing to files or directories in another filesystem, having a different inode and permissions than the original file or directory, and having a small size. By acting as a pointer to the original content and not being a mirror of it, its size is only the number of bytes necessary to compose the name of the file or directory.
[ Learn how to manage your Linux environment for success. ]
Symbolic links have limitations, however. Because you're just creating a pointer to a directory, if you change the original directory name or location, then you "break" your pointer. Your symbolic link cannot find the file or directory it's linked to anymore unless you change the original object back to the name or location you used when you created the symbolic link. Also, symbolic links don't inherit the original permissions from the original file. That means any permission changes made in the original file aren't reflected in the symbolic link.
Create soft links
To create a symbolic link, use the ln
command, which is the same command and syntax used for hard links, except that you include the -s
option. Here's an example:
$ ln -s /tmp/hard ./dir/soft
$ ls -li dir/
total 0
25811328 lrwxrwxrwx. 1 localuser localuser 9 set 20 13:13 soft -> /tmp/hard
$ ln -s /home/localuser/dir/ /tmp/softdir
$ ls -li
total 0
25606589 drwxrwxr-x. 2 localuser localuser 18 set 20 13:13 dir
$ ls -li /tmp/
total 4
25606591 -rw-rw-r--. 1 localuser localuser 2 set 19 16:54 hard
8410604 lrwxrwxrwx. 1 localuser localuser 20 set 20 13:18 softdir -> /home/localuser/dir/
If you're working in a shell with a colored ls
command, the created symbolic link for a file or directory has an aqua or blue-green color, while the original file has a white color and the original directory has a dark blue color. These colors allow you to identify a symbolic link and the original content easily. Also, the created symbolic links for the file and the directory have different inode addresses than the originals.
Finally, the sizes and permissions are different for the file symbolic link, too. Compare the following examples:
$ stat dir/
File: dir/
Size: 18 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 25606589 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-20 13:13:25.137000000 -0300
Modify: 2022-09-20 13:13:15.527000000 -0300
Change: 2022-09-20 13:13:15.527000000 -0300
Birth: 2022-09-19 15:21:27.616000000 -0300
$ stat /tmp/softdir/
File: /tmp/softdir/
Size: 18 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 25606589 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-20 13:13:25.137000000 -0300
Modify: 2022-09-20 13:13:15.527000000 -0300
Change: 2022-09-20 13:13:15.527000000 -0300
Birth: 2022-09-19 15:21:27.616000000 -0300
$ stat /tmp/hard
File: /tmp/hard
Size: 2 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 25606591 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-19 16:56:22.024000000 -0300
Modify: 2022-09-19 16:54:59.123000000 -0300
Change: 2022-09-19 16:56:03.380000000 -0300
Birth: 2022-09-19 15:29:40.276000000 -0300
$ stat dir/soft
File: dir/soft -> /tmp/hard
Size: 9 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 25811328 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-09-20 13:13:25.137000000 -0300
Modify: 2022-09-20 13:13:15.527000000 -0300
Change: 2022-09-20 13:13:15.527000000 -0300
Birth: 2022-09-20 13:13:15.527000000 -0300
Note that the symbolic link created for the file does not consume any disk blocks and has a size of nine (the length of the /tmp/hard
full path) precisely because it's only a pointer. You can manipulate the symbolic link the same way you would the original file, and the changes made to its contents are reflected in the original one:
$ cat dir/soft
0
$ cat /tmp/hard
0
$ echo 1 > dir/soft
$ cat dir/soft
1
$ cat /tmp/hard
1
Update a symbolic link
If you move a file or directory that a symbolic link points to, the connection is broken:
$ mv ~/dir ~/moved
$ cd /tmp/softdir
bash: cd: dir: No such file or directory
You can update a symbolic link using the -f
option:
$ ln -sf ~/moved /tmp/softdir
$ ls -l /tmp/softdir
lrwxrwxrwx 1 localuser...3 Oct 3 18:42 softdir -> moved
[ Get the guide to installing applications on Linux. ]
Remove a file
When you delete the file a symbolic link points to, the connection is severed (and the data is gone instantly, unlike with a hard link). See how the two differ below:
$ rm /tmp/hard
$ ls -li /tmp/
total 0
8410604 lrwxrwxrwx. 1 localuser localuser 20 set 20 13:18 softdir -> /home/localuser/dir/
$ ls -li dir/
total 0
25811328 lrwxrwxrwx. 1 localuser localuser 9 set 20 13:13 soft ->
$ file dir/soft
dir/soft: broken symbolic link to /tmp/hard
$ cat dir/soft
cat: dir/soft: No such file or directory
If you're using a terminal with a colored ls
command, you can see the output of a dark red color for the symbolic link name and a blinking white text with a light red background for the original file that doesn't exist anymore. The file
command shows that your symbolic link is now broken. What happens if you try to write something into your broken symbolic link?
$ ls -li /tmp/
total 0
8410604 lrwxrwxrwx. 1 localuser localuser 20 set 20 13:18 softdir -> /home/localuser/dir/
$ echo 0 > dir/soft
$ ls -li dir/soft
25606591 lrwxrwxrwx. 1 localuser localuser 9 set 20 13:39 dir/soft -> /tmp/hard
$ file dir/soft
dir/soft: symbolic link to /tmp/hard
$ ls -li /tmp/hard
8410609 -rw-rw-r--. 1 localuser localuser 2 set 20 13:44 /tmp/hard
$ stat /tmp/hard
File: /tmp/hard
Size: 2 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 8410609 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/localuser) Gid: ( 1000/localuser)
Context: unconfined_u:object_r:user_tmp_t:s0
Access: 2022-09-20 13:44:55.300000000 -0300
Modify: 2022-09-20 13:44:55.300000000 -0300
Change: 2022-09-20 13:44:55.300000000 -0300
Birth: 2022-09-20 13:44:55.300000000 -0300
It creates a new file with the same name in the same path that the symbolic link was pointing to with your newly added content.
But the same thing won't happen when it comes to directories:
$ rm -rf dir/
$ ls -li
$ ls -li /tmp/
total 4
8410609 -rw-rw-r--. 1 localuser localuser 2 set 20 13:44 hard
8410604 lrwxrwxrwx. 1 localuser localuser 20 set 20 13:18 softdir ->
$ cd /tmp/softdir
-bash: cd: /tmp/softdir: No such file or directory
$ file /tmp/softdir
/tmp/softdir: broken symbolic link to /home/localuser/dir/
$ echo 0 > /tmp/softdir/soft
-bash: /tmp/softdir/soft: No such file or directory
The same color scheme described before for broken links applies here. You won't be able to access the original directory through its broken symbolic link or by trying to create content inside the file that was there. It won't recreate a directory, meaning you've lost everything and the symbolic link is indeed broken, unless you create another directory (a new one) with the same name and the same location as the original one:
$ pwd
/home/localuser
$ mkdir dir
$ ls -li
total 0
21451985 drwxrwxr-x. 2 localuser localuser 6 set 20 13:55 dir
$ ls -li /tmp/
total 4
8410609 -rw-rw-r--. 1 localuser localuser 2 set 20 13:44 hard
8410604 lrwxrwxrwx. 1 localuser localuser 20 set 20 13:18 softdir -> /home/localuser/dir/
$ cd /tmp/softdir
$ pwd
/tmp/softdir
$ touch file
$ ls -li
total 0
21451986 -rw-rw-r--. 1 localuser localuser 0 set 20 13:56 file
$ ls -li /home/localuser/dir/
total 0
21451986 -rw-rw-r--. 1 localuser localuser 0 set 20 13:56 file
When working with symbolic links, make sure to always have the original content in place to avoid having broken links on your system.
Wrap up
As a sysadmin, you must understand and know how to create and manipulate hard and symbolic links, as well as the concepts behind them. This skill gives you a complete set of resources and possibilities to streamline, facilitate, improve, and automate the administration of your system. I hope this and my previous article about hard links helps you understand this topic, helps your Linux certification path, and adds to your general sysadmin knowledge.
About the author
Alexon has been working as a Senior Technical Account Manager at Red Hat since 2018, working in the Customer Success organization focusing on Infrastructure and Management, Integration and Automation, Cloud Computing, and Storage Solutions. He is a part of the TAM Practices LATAM team based in São Paulo, Brazil, where his job is partnering with, advocating, trust-advising, and supporting customers in their success goals while making use of the complete portfolio. He also contributes to produce and enhance documentation, knowledge-base articles, blog posts, presentations, webinars, and workshops. He is a member of numerous communities in addition to the Sudoers, like Red Hat Academy and Red Hat Accelerators. When he’s not at work, he enjoys spending quality time with his family (wife, daughter, and cat) and participating in several volunteer jobs.
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Original shows
Entertaining stories from the makers and leaders in enterprise tech
Products
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Cloud services
- See all products
Tools
- Training and certification
- My account
- Customer support
- Developer resources
- Find a partner
- Red Hat Ecosystem Catalog
- Red Hat value calculator
- Documentation
Try, buy, & sell
Communicate
About Red Hat
We’re the world’s leading provider of enterprise open source solutions—including Linux, cloud, container, and Kubernetes. We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.
Select a language
Red Hat legal and privacy links
- About Red Hat
- Jobs
- Events
- Locations
- Contact Red Hat
- Red Hat Blog
- Diversity, equity, and inclusion
- Cool Stuff Store
- Red Hat Summit