You've learned to copy, move, and delete files. Now it's time to understand linkingβone of Linux's most powerful yet misunderstood features. Links allow multiple filenames to point to the same data, saving disk space and enabling flexible file organization.
Understanding the difference between hard links and symbolic links (symlinks) is critical for the LFCS exam and real-world system administration. Get this wrong, and you might accidentally break applications or lose data.
π― What You'll Learn:
- Understanding what links are and why they exist
- What inodes are and how they work
- Creating hard links with
ln - Creating symbolic (soft) links with
ln -s - Key differences between hard and symbolic links
- When to use each type of link
- How links behave when files are deleted or moved
- Finding and identifying links on your system
- Real-world use cases for linking
Series: LFCS Certification - Phase 1 (Post 27 of 52)
Understanding File Storage and Inodes
Before diving into links, you need to understand how Linux actually stores files.
What is an Inode?
An inode (index node) is a data structure that stores information about a file:
- File size
- Permissions (owner, group, permissions)
- Timestamps (atime, mtime, ctime)
- Owner UID and GID
- Location of actual data blocks on disk
What the inode does NOT store: The filename!
How Files Really Work
Filename β Directory Entry β Inode Number β Inode β Data Blocks
Example:
$ ls -li hosts
55550 -rw-r--r--. 1 centos9 centos9 158 Oct 31 21:36 hosts
Breaking this down:
55550= Inode number1= Link count (number of names pointing to this inode)hosts= Filename (stored in directory, not in inode)
π‘ Key Concept: The filename is just a "pointer" to an inode. The inode points to the actual file data. This separation is what makes links possible!
The Separation of Name and Data
Think of it like this:
- Filename: Like a nickname or contact name in your phone
- Inode: Like the actual phone number
- Data: The person you're calling
Multiple nicknames (filenames) can point to the same phone number (inode), which reaches the same person (data).
Hard Links: Multiple Names for the Same Data
A hard link creates an additional filename that points to the same inode as an existing file.
Creating a Hard Link
$ cp /etc/hosts .
$ ls -li hosts
55550 -rw-r--r--. 1 centos9 centos9 158 Oct 31 21:36 hosts
Create hard link:
$ ln hosts hardhosts
$ ls -il hosts hardhosts
55550 -rw-r--r--. 2 centos9 centos9 158 Oct 31 21:36 hardhosts
55550 -rw-r--r--. 2 centos9 centos9 158 Oct 31 21:36 hosts
What happened:
- Same inode number (55550) for both files
- Link count increased from 1 to 2
- Same size, same permissions, same everything
- They ARE the same file with two different names
Hard Links Share Everything
$ echo hello >> hosts
$ ls -il hosts hardhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hardhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hosts
Both files:
- Have the new size (164 bytes)
- Contain the same data
- Point to identical data blocks
Why? Because they're the same file! Modifying data through either name modifies the same inode.
Hard Link Characteristics
| Characteristic | Description |
|---|---|
| Same Inode | Both names point to the exact same inode number |
| Same Data | Changes to one are reflected in the other instantly |
| Link Count | Tracks how many names point to this inode |
| No Space Used | Hard link uses no additional disk space (just a directory entry) |
| Same Filesystem | Can only link files on the same filesystem/partition |
| Files Only | Cannot hard link directories (prevents filesystem loops) |
| Deletion Behavior | Data survives until link count reaches 0 |
Deleting Hard Links
$ rm hosts
$ ls -il hosts hardhosts
ls: cannot access 'hosts': No such file or directory
55550 -rw-r--r--. 1 centos9 centos9 164 Oct 31 21:38 hardhosts
What happened:
hostsfilename removed- Link count decreased from 2 to 1
- Data still exists! (hardhosts still points to inode 55550)
- No data loss because link count > 0
The data is only deleted when the last link is removed (link count reaches 0).
Symbolic Links: Pointers to Filenames
A symbolic link (symlink or soft link) is a special file that contains a path to another file.
Creating a Symbolic Link
$ ln -s hosts symhosts
$ ls -il hosts hardhosts symhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hardhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hosts
391520 lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:39 symhosts -> hosts
Key observations:
- Different inode (391520 vs 55550)
- File type
l(link) instead of-(regular file) - Permissions
rwxrwxrwx(always full permissions - actual access determined by target) - Small size (5 bytes - just stores "hosts")
- Arrow notation (
-> hosts) shows target
Symbolic Link Characteristics
| Characteristic | Description |
|---|---|
| Different Inode | Symlink has its own inode number |
| Contains Path | Stores the target's pathname (as text) |
| Small Size | Only as large as the pathname it stores |
| Cross Filesystem | Can link across different filesystems/partitions |
| Can Link Dirs | Can create symlinks to directories |
| Broken Links | Can point to nonexistent files (becomes "broken") |
| Extra Lookup | Requires two steps: read link, then access target |
Creating Multiple Symlinks
$ ln -s hosts symhosts2
$ ls -il hosts hardhosts symhosts symhosts2
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hardhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hosts
391520 lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:39 symhosts -> hosts
391522 lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:40 symhosts2 -> hosts
Notice:
- Each symlink has its own unique inode (391520, 391522)
- Both symlinks point to the same target (
hosts) - Link count of
hostsunchanged (still 2 - symlinks don't affect hard link count)
Broken Symbolic Links
Symlinks can become "broken" if the target is deleted or moved.
Moving a Symlink (Breaks It)
$ mv symhosts2 /tmp
$ ls -l /tmp/symhosts2
lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:40 /tmp/symhosts2 -> hosts
Problem: Symlink still points to hosts, but from /tmp perspective, hosts doesn't exist there!
Deleting the Target (Breaks Symlink)
$ rm hosts
$ ls -il hosts hardhosts symhosts
ls: cannot access 'hosts': No such file or directory
55550 -rw-r--r--. 1 centos9 centos9 164 Oct 31 21:38 hardhosts
391520 lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:39 symhosts -> hosts
$ cat symhosts
cat: symhosts: No such file or directory
What happened:
hostsdeletedhardhostsstill works (hard link, same inode)symhostsis broken (points to nonexistent "hosts")
Fixing a Broken Symlink
$ ln hardhosts hosts
$ ls -il hosts hardhosts symhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hardhosts
55550 -rw-r--r--. 2 centos9 centos9 164 Oct 31 21:38 hosts
391520 lrwxrwxrwx. 1 centos9 centos9 5 Oct 31 21:39 symhosts -> hosts
$ cat symhosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
hello
Fixed! Because hosts exists again, symlink works.
Hard Links vs Symbolic Links
Hard Links
- β Same inode as original
- β True duplicate (indistinguishable)
- β No extra disk space
- β Survives file deletion
- β Same filesystem only
- β Cannot link directories
- β Cannot cross filesystems
- β No broken links possible
- β Slightly faster (direct)
Symbolic Links
- β Different inode
- β Clearly marked as link
- β Tiny disk space (path length)
- β Breaks if target deleted
- β Can cross filesystems
- β Can link directories
- β Can link to anything
- β Can become broken
- β Slightly slower (indirection)
When to Use Each Type
Use Hard Links When:
- You need backup protection (file survives deletion)
- Working within same filesystem
- Linking regular files only
- You want true duplicates with shared data
Use Symbolic Links When:
- Linking across filesystems/partitions
- Linking to directories
- Creating shortcuts in different locations
- You want to clearly see what's a link
- Target location might change
The ln Command
Basic Syntax
# Hard link
ln TARGET LINK_NAME
# Symbolic link
ln -s TARGET LINK_NAME
Common ln Options
| Option | Purpose |
|---|---|
-s | Create symbolic link instead of hard link |
-f | Force - remove existing destination files |
-i | Interactive - prompt before overwriting |
-v | Verbose - show what's being created |
-r | Relative - create symlink relative to link location |
System Symlinks
Linux uses symlinks extensively in the root filesystem:
$ ls -l /
lrwxrwxrwx. 1 root root 7 Jun 25 2024 bin -> usr/bin
lrwxrwxrwx. 1 root root 7 Jun 25 2024 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Jun 25 2024 lib64 -> usr/lib64
lrwxrwxrwx. 1 root root 8 Jun 25 2024 sbin -> usr/sbin
Why? Compatibility! Old software expects /bin, but modern systems consolidate in /usr/bin. Symlinks maintain backward compatibility.
Real-World Use Cases
1. Version Management
# Keep multiple versions
/opt/app-1.0/
/opt/app-1.1/
/opt/app-2.0/
# Symlink points to current version
ln -s /opt/app-2.0 /opt/app
# To switch versions:
rm /opt/app
ln -s /opt/app-1.1 /opt/app
2. Configuration Management
# Original config in version control
/etc/nginx/sites-available/mysite.conf
# Symlink to enable
ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/mysite.conf
# To disable (just remove symlink)
rm /etc/nginx/sites-enabled/mysite.conf
3. Shared Libraries
# Multiple versions exist
/lib/libfoo.so.1.0.0
/lib/libfoo.so.1.1.0
# Symlink for programs to find
ln -s /lib/libfoo.so.1.1.0 /lib/libfoo.so.1
ln -s /lib/libfoo.so.1 /lib/libfoo.so
4. Home Directory Shortcuts
# Quick access to frequently used directories
ln -s /var/log/nginx ~/nginx-logs
ln -s /var/www/html ~/website
ln -s /mnt/backup ~/backup
5. Cross-Filesystem Links
# Hard link fails (different filesystems)
ln /mnt/external/data.txt ~/data.txt
ln: failed to create hard link: Invalid cross-device link
# Symlink works!
ln -s /mnt/external/data.txt ~/data.txt
Finding Links
Find Hard Links
# Find all files with inode 55550
find / -inum 55550 2>/dev/null
# Find files with link count > 1
find /home -type f -links +1
Find Symbolic Links
# Find all symlinks
find /etc -type l
# Find broken symlinks
find /home -xtype l
Check Link Count
$ ls -l filename
-rw-r--r--. 2 user user 1024 Dec 17 10:00 filename
^
Link count
π§ͺ Practice Labs
Lab 1: Creating Hard Links (Beginner)
Task: Create a file and a hard link to it. Verify they share the same inode and modify one to see changes in both.
Show Solution
# Create original file
echo "original data" > file1.txt
# Check inode
ls -li file1.txt
# Example: 12345 -rw-r--r--. 1 user user 14 ... file1.txt
# Create hard link
ln file1.txt file1_hardlink.txt
# Compare inodes
ls -li file1.txt file1_hardlink.txt
# Both should show same inode number and link count of 2
# Modify through first name
echo "added line" >> file1.txt
# Check both files
cat file1.txt
cat file1_hardlink.txt
# Both show the same content!
# Check sizes
ls -l file1.txt file1_hardlink.txt
# Identical sizes
Key concept: Hard links share the same inode, so changes appear in both.
Lab 2: Creating Symbolic Links (Beginner)
Task: Create a file and a symbolic link to it. Verify the symlink has a different inode.
Show Solution
# Create original file
echo "symlink target" > target.txt
# Create symbolic link
ln -s target.txt link.txt
# Compare with ls -li
ls -li target.txt link.txt
# Different inode numbers!
# link.txt shows: lrwxrwxrwx ... link.txt -> target.txt
# Verify symlink works
cat link.txt
# Shows content of target.txt
# Check file types
file target.txt
# target.txt: ASCII text
file link.txt
# link.txt: symbolic link to target.txt
Key concept: Symlinks have their own inode and store the target path.
Lab 3: Understanding Link Counts (Beginner)
Task: Create a file with multiple hard links and observe the link count.
Show Solution
# Create file
touch original.txt
ls -l original.txt
# -rw-r--r--. 1 user user 0 ... original.txt
# ^ link count = 1
# Add first hard link
ln original.txt link1.txt
ls -l original.txt
# -rw-r--r--. 2 user user 0 ... original.txt
# ^ link count = 2
# Add second hard link
ln original.txt link2.txt
ls -l original.txt link1.txt link2.txt
# All show link count = 3
# Delete one link
rm link1.txt
ls -l original.txt link2.txt
# Both show link count = 2
# Delete another
rm link2.txt
ls -l original.txt
# Link count = 1
# Data only deleted when count reaches 0
rm original.txt
# Now data is actually deleted
Key concept: Link count tracks how many names point to the inode.
Lab 4: Broken Symbolic Links (Intermediate)
Task: Create a symlink, delete the target, and observe the broken link.
Show Solution
# Create target
echo "data" > target.txt
# Create symlink
ln -s target.txt mylink.txt
# Verify it works
cat mylink.txt
# Shows: data
# Delete target
rm target.txt
# Try to access symlink
cat mylink.txt
# Error: cat: mylink.txt: No such file or directory
# Symlink still exists but is broken
ls -l mylink.txt
# lrwxrwxrwx ... mylink.txt -> target.txt
# Find broken symlinks
find . -xtype l
# ./mylink.txt
# Recreate target to fix
echo "new data" > target.txt
cat mylink.txt
# Works again: new data
Key concept: Symlinks can become broken if target is deleted.
Lab 5: Cross-Filesystem Links (Intermediate)
Task: Attempt to create a hard link across filesystems and use a symlink instead.
Show Solution
# Create file in home
echo "data" > ~/myfile.txt
# Try hard link to /tmp (often different filesystem)
ln ~/myfile.txt /tmp/hardlink.txt
# Error: ln: failed to create hard link: Invalid cross-device link
# Check filesystems
df ~/myfile.txt
df /tmp
# Often different devices
# Symlink works across filesystems
ln -s ~/myfile.txt /tmp/symlink.txt
# Verify
ls -l /tmp/symlink.txt
cat /tmp/symlink.txt
# Clean up
rm ~/myfile.txt /tmp/symlink.txt
Key concept: Hard links require same filesystem; symlinks work across filesystems.
Lab 6: Linking Directories (Intermediate)
Task: Demonstrate that hard links cannot link directories, but symlinks can.
Show Solution
# Create directory
mkdir mydir
touch mydir/file1.txt mydir/file2.txt
# Try hard link to directory
ln mydir mydir_hardlink
# Error: ln: mydir: hard link not allowed for directory
# Symlink works for directories
ln -s mydir mydir_symlink
# Verify
ls -ld mydir_symlink
# lrwxrwxrwx ... mydir_symlink -> mydir
# Access through symlink
ls mydir_symlink/
# file1.txt file2.txt
cd mydir_symlink
pwd
# Shows the symlink path
# Clean up
cd ..
rm mydir_symlink
rm -r mydir
Key concept: Only symlinks can link to directories.
Lab 7: Verbose Link Creation (Intermediate)
Task: Use verbose mode to see what ln is doing.
Show Solution
# Create files
touch file1.txt file2.txt file3.txt
# Verbose hard link
ln -v file1.txt file1_link.txt
# Output: 'file1_link.txt' => 'file1.txt'
# Verbose symlink
ln -sv file2.txt file2_link.txt
# Output: 'file2_link.txt' -> 'file2.txt'
# Multiple links with verbose
ln -v file3.txt link_a.txt
ln -v file3.txt link_b.txt
ln -v file3.txt link_c.txt
# Verify link count
ls -l file3.txt
# Should show link count = 4
# Clean up
rm file*.txt link*.txt
Key concept: Verbose mode shows what's being linked.
Lab 8: Finding All Hard Links (Intermediate)
Task: Create multiple hard links and find them all by inode number.
Show Solution
# Create file
echo "shared data" > original.txt
# Note the inode
ls -i original.txt
# Example: 98765 original.txt
INODE=$(ls -i original.txt | awk '{print $1}')
# Create hard links in different locations
ln original.txt ~/link1.txt
mkdir subdir
ln original.txt subdir/link2.txt
# Find all links to this inode
find ~ -inum $INODE 2>/dev/null
# Expected output:
# /home/user/original.txt
# /home/user/link1.txt
# /home/user/subdir/link2.txt
# Verify they all share same inode
ls -li original.txt ~/link1.txt subdir/link2.txt
# Clean up
rm original.txt ~/link1.txt subdir/link2.txt
rmdir subdir
Key concept: Use -inum to find all hard links to an inode.
Lab 9: Symlink to Symlink (Advanced)
Task: Create a chain of symbolic links and understand the behavior.
Show Solution
# Create original file
echo "final data" > original.txt
# Create first symlink
ln -s original.txt link1.txt
# Create symlink to symlink
ln -s link1.txt link2.txt
# Create another level
ln -s link2.txt link3.txt
# All work
cat link3.txt
# Shows: final data
# Show the chain
ls -l link*.txt
# link1.txt -> original.txt
# link2.txt -> link1.txt
# link3.txt -> link2.txt
# Break the chain by removing middle link
rm link2.txt
# Now link3 is broken
cat link3.txt
# Error: No such file or directory
# Clean up
rm original.txt link1.txt link3.txt
Key concept: Symlinks can point to other symlinks, creating chains.
Lab 10: Relative vs Absolute Symlinks (Advanced)
Task: Create both relative and absolute symlinks and understand the difference.
Show Solution
# Create structure
mkdir project
cd project
echo "data" > file.txt
# Absolute symlink
ln -s /home/$(whoami)/project/file.txt abs_link.txt
# Relative symlink
ln -s file.txt rel_link.txt
# Both work from current directory
cat abs_link.txt
cat rel_link.txt
# Move to parent directory
cd ..
# Absolute still works
cat project/abs_link.txt
# Relative broken (looking for ../file.txt from project/)
cat project/rel_link.txt
# Error if file.txt not in parent
# Move entire project directory
mv project project_moved
# Relative link still works (moves with directory)
cat project_moved/rel_link.txt
# Absolute link broken (points to old location)
cat project_moved/abs_link.txt
# Error: points to /home/user/project/file.txt (old location)
# Clean up
rm -rf project_moved
Key concept: Relative symlinks are more portable when moving directories.
Lab 11: Version Switching with Symlinks (Advanced)
Task: Simulate version management using symbolic links.
Show Solution
# Create versioned directories
mkdir -p /tmp/app-v1.0 /tmp/app-v1.1 /tmp/app-v2.0
# Add version-specific files
echo "Version 1.0" > /tmp/app-v1.0/version.txt
echo "Version 1.1" > /tmp/app-v1.1/version.txt
echo "Version 2.0" > /tmp/app-v2.0/version.txt
# Create current symlink
ln -s /tmp/app-v2.0 /tmp/app-current
# Check current version
cat /tmp/app-current/version.txt
# Version 2.0
# Rollback to v1.1
rm /tmp/app-current
ln -s /tmp/app-v1.1 /tmp/app-current
# Verify
cat /tmp/app-current/version.txt
# Version 1.1
# Upgrade to v2.0
ln -sf /tmp/app-v2.0 /tmp/app-current
# Verify
cat /tmp/app-current/version.txt
# Version 2.0
# Clean up
rm -rf /tmp/app-*
Key concept: Symlinks enable instant version switching.
Lab 12: Finding Broken Symlinks (Advanced)
Task: Create several symlinks, break some, and find all broken ones.
Show Solution
# Create files
touch file1.txt file2.txt file3.txt
# Create symlinks
ln -s file1.txt link1.txt
ln -s file2.txt link2.txt
ln -s file3.txt link3.txt
ln -s nonexistent.txt link4.txt # Already broken
# All symlinks listed
ls -l link*.txt
# Delete some targets
rm file2.txt file3.txt
# Find broken symlinks
find . -xtype l
# ./link2.txt
# ./link3.txt
# ./link4.txt
# Alternative: use test in a loop
for link in link*.txt; do
if [ ! -e "$link" ]; then
echo "Broken: $link"
fi
done
# Remove all broken symlinks
find . -xtype l -delete
# Verify only working symlink remains
ls -l link*.txt
# Only link1.txt remains
# Clean up
rm file1.txt link1.txt
Key concept: Use find -xtype l to find broken symlinks.
Lab 13-20: Additional Advanced Labs
Due to space, here are summaries of remaining labs:
Lab 13: Hard link backup strategy (create backups with hard links to save space) Lab 14: Nginx sites-enabled pattern (symlink config files to enable/disable) Lab 15: Library versioning (manage .so files with symlinks) Lab 16: Symlink permissions behavior (understand rwx vs target permissions) Lab 17: Circular symlink detection (create and detect symlink loops) Lab 18: Mass symlink creation (link multiple files at once) Lab 19: Symlink resolution in scripts (use readlink to resolve) Lab 20: inode exhaustion demonstration (create many hard links)
π Best Practices
| DO β | DON'T β |
|---|---|
| Use absolute paths for system symlinks | Create circular symlink chains |
| Use relative paths for portable symlinks | Hard link across filesystems (won't work) |
| Check for broken symlinks regularly | Assume symlinks always work |
| Use symlinks for version management | Hard link directories (not allowed) |
| Document symlink purposes | Delete targets without checking links |
| Use ls -li to verify links | Confuse link types (hard vs symbolic) |
π¨ Common Pitfalls
- Confusing hard and symbolic links - Check inode numbers
- Breaking symlinks by moving targets - Use absolute paths for stable targets
- Trying to hard link directories - Use symlinks instead
- Cross-filesystem hard links - Won't work, use symlinks
- Not checking for broken symlinks - Use
find -xtype l - Creating circular symlink loops - Causes infinite loops
π Command Cheat Sheet
# Hard links
ln source.txt link.txt # Create hard link
ls -li file.txt # Show inode and link count
find / -inum 12345 # Find all links to inode
find /home -type f -links +1 # Find files with multiple links
# Symbolic links
ln -s source.txt link.txt # Create symlink
ln -s /abs/path link.txt # Absolute symlink
ln -s ../relative/path link.txt # Relative symlink
ls -l link.txt # Show symlink target
readlink link.txt # Print symlink target
readlink -f link.txt # Resolve to final target
# Finding links
find /etc -type l # Find all symlinks
find /home -xtype l # Find broken symlinks
find . -inum 12345 2>/dev/null # Find hard links by inode
# Managing links
ln -sf new_target link.txt # Force update symlink
rm link.txt # Remove link (not target)
unlink link.txt # Alternative remove command
π― Key Takeaways
Master These Concepts:
- Inodes separate names from data - Filenames point to inodes, inodes point to data
- Hard links share inodes - Multiple names, same data, same inode
- Symlinks store paths - Different inode, contains target pathname
- Hard links survive deletion - Data persists while link count > 0
- Symlinks can break - Target deletion breaks symlink
- Hard links: same filesystem - Cannot cross filesystem boundaries
- Symlinks: anywhere - Can cross filesystems and link directories
- Link count matters - Shows how many hard links exist
- Use ls -li - Shows inodes and link counts
- System uses symlinks extensively - /bin β /usr/bin for compatibility
Quick Decision Guide:
- Same filesystem, want backup protection β Hard link
- Cross filesystem or linking directory β Symbolic link
- Version management or shortcuts β Symbolic link
- Space-efficient backup β Hard link
π What's Next?
Coming Up Next:
- Post 28: Finding Files with the find Command
- Post 29: Viewing File Contents (cat, less, more, head, tail)
- Post 30: Introduction to Text Editors (vi/vim basics)
π Congratulations! You now understand Linux linking! You've learned:
- How inodes separate filenames from data
- Creating and managing hard links
- Creating and managing symbolic links
- Key differences and when to use each
- Finding and fixing broken links
- Real-world applications of linking
Links are fundamental to Linux system organization. Understanding them deeply will help you troubleshoot issues, manage disk space efficiently, and understand how Linux really works under the hood! π

