Hard Links and Symbolic Links in Linux
Two names, one file — Linux links let you reference files from multiple locations. Understand the difference between hard links and symlinks, and when to use each.
Linux filesystems separate a file's name (directory entry) from its data (inode). A link is just another name pointing to the same data. There are two kinds:
- Hard link — a second directory entry pointing to the same inode (data block)
- Symbolic link (symlink) — a file that contains a path pointing to another file
Understanding this distinction explains many behaviours that seem strange at first.
Hard Links vs Symbolic Links
Hard Link vs Symbolic Link Comparison
| Feature | Hard Link | Symbolic Link |
|---|---|---|
| Command | ln file link | ln -s file link |
| Points to | Same inode (data) | A file path |
| Cross filesystems | ❌ No | ✅ Yes |
| Link directories | ❌ No | ✅ Yes |
| Original deleted | ✅ Data still accessible | ❌ Link breaks (dangling) |
Shows in ls -l | - (same type as original) | l prefix + → target |
| Size | Same as original | Tiny (just the path length) |
Syntax
ln TARGET LINK_NAME # Create a hard link
ln -s TARGET LINK_NAME # Create a symbolic link (-s for symlink)Hard Links in Practice
A hard link is a second directory entry for the same data. The "link count" in ls -l (the number after permissions) shows how many hard links point to the inode. Data is only freed when the link count reaches zero (all names deleted).
echo "Hello World" > original.txt
ln original.txt hardlink.txt
# Both refer to identical data
cat original.txt # Hello World
cat hardlink.txt # Hello World
# Modify through one — both see the change (same data!)
echo "More content" >> hardlink.txt
cat original.txt # Hello World
More content
# Check they share the same inode
ls -li original.txt hardlink.txt
# 12345 -rw-r--r-- 2 sagar staff 22 ... original.txt
# 12345 -rw-r--r-- 2 sagar staff 22 ... hardlink.txt
# ↑ Same inode ↑ Link count = 2
# Delete original — hard link keeps the data alive!
rm original.txt
cat hardlink.txt # Hello World
More content — still works!Symbolic Links in Practice
A symlink stores a path. When you read through a symlink, the OS follows the path to find the real file. If the target moves or is deleted, the symlink becomes dangling (broken).
echo "Hello World" > original.txt
ln -s original.txt sym.txt
# Works normally
cat sym.txt # Hello World
# ls shows the link and its target
ls -l sym.txt
# lrwxrwxrwx 1 sagar staff 12 ... sym.txt -> original.txt
# ↑ 'l' for symlink
# Delete original — symlink breaks!
rm original.txt
cat sym.txt # cat: sym.txt: No such file or directory
# sym.txt is now a "dangling" symlink
# Find broken symlinks
find . -type l ! -exec test -e {} ; -print
# Symlinks can point to directories
ln -s /var/log ~/logs
ls ~/logs # Lists /var/log contents
cd ~/logs # Same as cd /var/logManaging Links
# See where a symlink points
readlink sym.txt # original.txt
readlink -f sym.txt # /home/sagar/original.txt (full resolved path)
# Remove a link WITHOUT deleting the target
rm sym.txt # Only removes the link, not what it points to
unlink sym.txt # Alternative command
# Common use cases for symlinks
ln -s python3.11 /usr/local/bin/python # Version management
ln -s /var/www/html/mysite ~/site # Quick access to deep directory
ln -s ~/dotfiles/.bashrc ~/.bashrc # Dotfile managementWhen to Use Which
Use hard links when you want a true backup that survives deletion of the original name — useful for space-efficient backups (same data, multiple names). Use symbolic links for everything else — version management, shortcuts to directories, config file management (dotfiles), and any cross-filesystem link. Symlinks are far more common in practice.
You create a symlink: `ln -s /etc/nginx/nginx.conf ~/nginx.conf`. Then you edit `~/nginx.conf`. What actually gets modified?
Experiment with both link types:
Hard link experiment:
- Create
echo "original" > file.txt - Create a hard link:
ln file.txt hard.txt - Check the inode numbers are the same with
ls -li - Delete
file.txtand confirmhard.txtstill works
Symlink experiment:
5. Recreate file.txt
6. Create a symlink: ln -s file.txt sym.txt
7. Run ls -l sym.txt — note the l prefix and the → arrow
8. Delete file.txt and try to read sym.txt — observe the broken link