Hard Links vs Soft Links
Linux has two types of links — hard links and symbolic (soft) links. They both look similar on the surface, but internally they work completely differently. Understanding them requires understanding inodes, which are how Linux actually tracks files.
The Key Insight: Files Are Not Their Names
What is the "real" identity of a file in Linux?
The inode. An inode is a data structure that stores a file's metadata (size, permissions, timestamps, data block locations) and has a unique number. The filename is just a human-readable label that points to an inode — it's stored in the directory, not in the inode itself.
$ ls -i hello.txt
1234567 hello.txt ← 1234567 is the inode number
$ stat hello.txt
File: hello.txt
Size: 42 Inode: 1234567 Links: 1
...
Hard Links — Another Name for the Same Inode
A hard link is just another directory entry pointing to the same inode. The file's actual data exists once on disk; two filenames point to it.
# Create a hard link
ln hello.txt hello-hardlink.txt
$ ls -i hello.txt hello-hardlink.txt
1234567 hello.txt
1234567 hello-hardlink.txt ← same inode number!
$ stat hello.txt
Inode: 1234567 Links: 2 ← link count increased
What happens when I delete the original?
Nothing! Deleting a file just removes one directory entry and decrements the link count. The inode (and data) is only freed when the link count reaches 0. So
rm hello.txt leaves hello-hardlink.txt fully intact.
Hard link limitations:
- Cannot link across different filesystems (inodes are filesystem-specific)
- Cannot link to directories (would create filesystem loops)
Symbolic Links — A File Containing a Path
A symbolic link (symlink) is a special file that contains a text path to another file or directory. When you access a symlink, the kernel follows the path stored in it.
# Create a symlink (ln -s)
ln -s /usr/bin/python3 /usr/local/bin/python
$ ls -la /usr/local/bin/python
lrwxrwxrwx 1 root root 16 Jan 1 /usr/local/bin/python -> /usr/bin/python3
# ↑ 'l' = symlink
$ ls -i /usr/local/bin/python /usr/bin/python3
9999 /usr/local/bin/python ← different inode numbers!
1234 /usr/bin/python3
What happens if I delete the original file a symlink points to?
The symlink breaks — it becomes a dangling symlink. When you try to access it, you get "No such file or directory." The symlink itself still exists; it just points to nothing.
Symlink advantages:
- Can cross filesystem boundaries
- Can link to directories
- Can point to relative or absolute paths
When to Use Which
| Hard Link | Symbolic Link | |
|---|---|---|
| Points to | Inode directly | File path (string) |
| Cross-filesystem | No | Yes |
| Link to directories | No | Yes |
| Breaks if original deleted | No (survives) | Yes (dangling) |
| Common use case | Backup systems, package managers | Versioning (python → python3.11), /etc/alternatives |