Linux CLI 4 🐧 Symbolic and Hard links
Links are special types of files that point to other files or directories. Linux has two kinds: symbolic links (soft links) and hard links. Understanding the difference is essential for working with the Linux filesystem.
Symbolic Links (Soft Links)
A symbolic link (also called a soft link) is a special file that acts as a reference to another file or directory. It’s like a shortcut or alias.
# Look if there is a file.txt
ln -s /home/test/file.txt link
ls -la
| Command | Description |
|---|---|
ln -s /home/test/file.txt link | Create a symbolic link named link pointing to /home/test/file.txt |
ls -la | List files with details — see the link |
How Symbolic Links Work
link ──────→ /home/test/file.txt ──────→ [data on disk]
(symlink) (actual file) (inode)
- The symlink contains the path to the target
- It’s a separate file with its own inode
- If you delete the target, the symlink breaks (dangling link)
Identifying Symbolic Links
When you run ls -la, the first character shows the file type:
lrwxrwxrwx 1 kronos users 24 Jan 15 10:30 link -> /home/test/file.txt
│└──┬───┘ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ └── Target path
│ │ │ │ │ │ │ └──────────── Link name
│ │ │ │ │ │ └──────────────────────── Modification date
│ │ │ │ │ └─────────────────────────── Size of the link
│ │ │ │ └──────────────────────────────── Group
│ │ │ └─────────────────────────────────────── Owner
│ │ └────────────────────────────────────────── Hard links
│ └────────────────────────────────────────────────── Permissions
└────────────────────────────────────────────────────── l = symbolic link
Key indicator: The first character is
l(lowercase L) and the output showslink -> target.
Creating Symbolic Links
ln -s <target> <link_name>
| Part | Description |
|---|---|
ln | The link command |
-s | Create a symbolic link (soft link) |
<target> | The file or directory to point to |
<link_name> | The name of the new symlink |
Examples:
# Link to a file
ln -s /home/test/file.txt link
# Creates: link -> /home/test/file.txt
# Link to a directory
ln -s /var/log logs
# Creates: logs -> /var/log
# Relative path link
ln -s ../Documents/notes.txt mynote
# Creates: mynote -> ../Documents/notes.txt
Use Cases for Symbolic Links
| Use Case | Example | Why |
|---|---|---|
| Aliases for frequent files | ln -s /etc/nginx/nginx.conf nginx | Type nginx instead of long path |
| Shortcuts to directories | ln -s /var/log ~/logs | Quick access to logs |
| Multiple versions of a file | ln -s v2.0 current | current always points to latest version |
| Cross-filesystem links | Symlinks work across partitions | Hard links can’t do this |
| Pointing to files with moving targets | ln -s /opt/app/current config | current can be updated to new versions |
Practical Example
# 1. Create a target file
$ echo "Hello, World!" > /home/test/file.txt
# 2. Create a symbolic link
$ ln -s /home/test/file.txt link
# 3. View the link
$ ls -la
lrwxrwxrwx 1 kronos users 24 Jan 15 10:30 link -> /home/test/file.txt
-rw-r--r-- 1 kronos users 14 Jan 15 10:30 file.txt
# 4. Read through the symlink
$ cat link
Hello, World!
# 5. Modify through the symlink
$ echo "Updated!" > link
$ cat /home/test/file.txt
Updated!
# 6. Delete the target — symlink becomes "broken"
$ rm /home/test/file.txt
$ cat link
cat: link: No such file or directory
# 7. Remove the broken link
$ rm link
Hard Links
A hard link is a special type of file that allows multiple filenames to refer to the same data on disk.
touch file.txt
cat file.txt
ln file.txt link1
ls -la
nano file.txt
cat link1
| Command | Description |
|---|---|
touch file.txt | Create an empty file |
cat file.txt | Show the contents of a file |
ln file.txt link1 | Create a hard link named link1 to file.txt |
ls -la | Check both files — same inode, same link count |
nano file.txt | Edit the original file |
cat link1 | Show contents of link1 — reflects changes |
How Hard Links Work
file.txt ──┐
├──→ [inode] ──→ [data on disk]
link1 ──┘
- Both filenames point to the same inode
- No separate file — they’re two names for the same data
- Deleting one name doesn’t affect the other
- Changes through one are visible through the other
The Inode
An inode (index node) is a data structure that stores metadata about a file:
| Inode stores | Does NOT store |
|---|---|
| Permissions | Filename |
| Owner / group | File contents |
| Size | — |
| Timestamps | — |
| Hard link count | — |
| Pointers to data blocks | — |
Key concept: Hard links share the same inode number — the filesystem sees them as the same file.
Identifying Hard Links
$ ls -la
total 8
drwxr-xr-x 2 kronos users 4096 Jan 15 10:30 .
drwxr-xr-x 5 kronos users 4096 Jan 15 10:30 ..
-rw-r--r-- 2 kronos users 14 Jan 15 10:30 file.txt
-rw-r--r-- 2 kronos users 14 Jan 15 10:30 link1
│
└── Same link count (2) — a hard link exists
Notice:
- Both files show link count
2 - No
->arrow (unlike symlinks) - Same size, same timestamps
- First character is
-(regular file)
Using ls -i to see inode numbers:
$ ls -i
12345678 file.txt
12345678 link1
Same inode number = same file. This is the definitive way to identify hard links.
Creating Hard Links
ln <target> <link_name>
| Part | Description |
|---|---|
ln | The link command |
<target> | The file to link to |
<link_name> | The new name |
Note: No
-sflag — that’s only for symlinks.
Examples:
# Create a hard link
ln file.txt link1
# Create multiple hard links
ln file.txt link2
ln file.txt link3
# All four share the same inode
ls -i
12345678 file.txt
12345678 link1
12345678 link2
12345678 link3
Modifying Data Through Hard Links
# 1. Create a file
$ echo "Original content" > file.txt
# 2. Create a hard link
$ ln file.txt link1
# 3. Both files show the same content
$ cat file.txt
Original content
$ cat link1
Original content
# 4. Edit one — both reflect the change
$ echo "Updated content" > file.txt
$ cat link1
Updated content
# 5. Delete the original — hard link still works
$ rm file.txt
$ cat link1
Updated content
# 6. Hard link count drops but data remains
$ ls -la link1
-rw-r--r-- 1 kronos users 16 Jan 15 10:30 link1
Hard Link vs Symbolic Link
| Feature | Hard Link | Symbolic Link |
|---|---|---|
| Command | ln target link | ln -s target link |
| Points to | Inode (data) | Path (filename) |
| Same inode? | ✅ Yes | ❌ No |
| Separate file? | ❌ No | ✅ Yes |
| Cross-filesystem? | ❌ No | ✅ Yes |
| Link to directory? | ❌ No (complex) | ✅ Yes |
| Broken if target deleted? | ❌ No (data persists) | ✅ Yes |
| Works on all filesystems? | Most, but not all | ✅ Yes |
ls -la shows | Same link count | -> arrow |
Visual comparison:
HARD LINK: SYMBOLIC LINK:
file.txt ──┐ link ──→ file.txt ──→ [data]
├──→ [inode] → [data] (separate file)
link1 ──┘ (points to name)
(same inode) (breaks if target gone)
Complete Example Session
# ============================================
# PART 1: SYMBOLIC LINKS
# ============================================
# 1. Create a file
$ mkdir -p /home/test
$ echo "Hello from test" > /home/test/file.txt
# 2. Create a symbolic link
$ ln -s /home/test/file.txt link
$ ls -la
lrwxrwxrwx 1 kronos users 24 Jan 15 10:30 link -> /home/test/file.txt
# 3. Read through symlink
$ cat link
Hello from test
# 4. Create a symlink to a directory
$ ln -s /var/log logs
$ ls -la logs
lrwxrwxrwx 1 kronos users 8 Jan 15 10:30 logs -> /var/log
$ ls logs
alternatives.log apt dmesg syslog ...
# 5. Delete target — symlink breaks
$ rm /home/test/file.txt
$ cat link
cat: link: No such file or directory
# 6. Remove the broken link
$ rm link
# ============================================
# PART 2: HARD LINKS
# ============================================
# 1. Create a file
$ touch file.txt
$ cat file.txt # Empty
# 2. Create a hard link
$ ln file.txt link1
$ ls -la
-rw-r--r-- 2 kronos users 0 Jan 15 10:30 file.txt
-rw-r--r-- 2 kronos users 0 Jan 15 10:30 link1
# Note: link count = 2
# 3. Confirm same inode
$ ls -i
12345678 file.txt
12345678 link1
# Same inode number!
# 4. Edit the original
$ nano file.txt
# (write "Hello from nano", save, exit)
# 5. Read through the hard link
$ cat link1
Hello from nano
# Change is reflected!
# 6. Delete original — hard link survives
$ rm file.txt
$ cat link1
Hello from nano
# Data still accessible!
# 7. Check link count
$ ls -la link1
-rw-r--r-- 1 kronos users 16 Jan 15 10:30 link1
# Count is now 1 — only one name remains
Quick Reference
Symbolic Links
| Command | Description |
|---|---|
ln -s target link | Create symbolic link |
ls -la | Shows link -> target |
rm link | Removes the link (not target) |
readlink link | Shows the target path |
Hard Links
| Command | Description |
|---|---|
ln target link | Create hard link |
ls -i | Shows inode numbers (identical) |
ls -la | Shows same link count |
rm file | Removes one name — data persists |
Comparison Table
| Aspect | Hard Link | Symbolic Link |
|---|---|---|
| Flag | (none) | -s |
| Points to | Inode | Path |
| Same inode | ✅ Yes | ❌ No |
| Target deleted | ✅ Still works | ❌ Broken |
| Cross-filesystem | ❌ No | ✅ Yes |
| Directories | ❌ No | ✅ Yes |
Best Practices
✅ Do This:
# Use symbolic links for most purposes
ln -s /var/log ~/logs
# Use -i to verify inode numbers
ls -i file.txt link1
# Use readlink to see where a symlink points
readlink link
# Use absolute paths for symlinks
ln -s /home/test/file.txt link # ✅ Works from anywhere
# Check link count to understand hard links
ls -la # Look at the number in column 2
❌ Don’t Do This:
# Don't use relative paths for symlinks you'll move
ln -s ../file.txt link # ⚠️ Breaks if you move the link
# Don't try to hard-link directories
ln /home /backup # ❌ Not allowed (or complex)
# Don't create hard links across filesystems
ln /mnt/usb/file.txt ~/link # ❌ Different filesystems
# Don't forget symlinks break if target is moved
mv /home/test/file.txt /home/test/moved.txt
cat link # ❌ Broken
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Symlink breaks | Target moved/deleted | Use absolute paths; recreate if broken |
| Hard link confusion | Doesn’t work across filesystems | Use symlink instead |
Forgetting -s | Creates hard link when symlink intended | Always add -s for symlinks |
| Deleting target | Symlink becomes broken | Remove the link too |
| Symlink loops | Link points to itself | Don’t create circular references |
Real-World Use Cases
1. Version Management (Symbolic Links)
# Deploy new version
/opt/app/v1.0/
/opt/app/v2.0/
/opt/app/current -> /opt/app/v2.0
# Update "current" to point to new version
ln -sfn /opt/app/v3.0 /opt/app/current
# -f = force, -n = treat as normal file (don't follow)
2. Configuration Aliases (Symbolic Links)
# Quick access to config
ln -s /etc/nginx/nginx.conf ~/nginx.conf
# Edit easily
nano ~/nginx.conf
3. Backup with Hard Links (Space-Efficient)
# Create snapshot without duplicating data
cp -al /data /backup/snapshot-$(date +%Y%m%d)
# -a = archive mode, -l = hard links (saves space!)
4. Log Rotation (Hard Links)
# Rotate logs while keeping access
mv /var/log/app.log /var/log/app.log.1
touch /var/log/app.log
# Or use hard links to avoid losing file handles
Summary
| Concept | Description |
|---|---|
| Symbolic link | Points to a path (like a shortcut) |
| Hard link | Points to the same inode (same data) |
ln -s | Create symbolic link |
ln | Create hard link |
ls -la | Shows link type (l) and target (->) |
ls -i | Shows inode numbers |
Key takeaways:
- Symbolic links are flexible — work across filesystems, can link to directories, break if target is deleted
- Hard links share the same data — survive deletion of the original, cannot cross filesystems, cannot link to directories
- Use
ln -sfor most cases — it’s the more versatile option - Use
ls -ito verify hard links (same inode number) - Use absolute paths for symlinks to avoid breakage
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!