4.2 Hard and Soft Links
Key Takeaways
- A hard link is an additional directory name for the same inode; ls -i shows matching inode numbers and the link count in ls -l increases.
- A soft (symbolic) link is a separate inode that stores a path string; create with ln -s target linkname and inspect with ls -l (shows arrow) or readlink.
- Hard links cannot cross filesystems and normally cannot name directories; symlinks can point across filesystems and to directories.
- Relative symlinks resolve from the link’s directory, not your current working directory; absolute symlinks break if the target path is moved even if relative layout is intact.
- Broken symlinks still exist as files but point nowhere—common exam trap when targets are deleted, renamed, or when relative paths were computed incorrectly.
4.2 Hard and Soft Links
Quick Answer: Hard link:
ln existing_file hardlink(same inode). Soft link:ln -s target symlink(stores a path). Check withls -li. Hard links stay valid if another name is removed; soft links break if their path target disappears or was written incorrectly.
The EX200 objective to create hard and soft links tests whether you understand names versus data. On Linux, users think in filenames; the kernel thinks in inodes. Links are how multiple names can refer to the same data—or how a name can point at another path.
Inodes, Names, and Link Counts
Every regular file has an inode containing metadata (permissions, ownership, timestamps, data block pointers). Directory entries map a name → inode number.
ls -li file.txt
stat file.txt
ls -iprints the inode number in the first column.ls -lshows the link count (second field after permissions)—how many directory entries reference that inode.
When the link count drops to zero and no process still has the file open, the filesystem reclaims the data. That is why deleting one hard-linked name does not necessarily delete the data if another hard link remains.
Hard Links
Creating hard links
ln original.txt hardlink.txt
ln /home/student/data/report.txt /home/student/shared/report.txt
Syntax: ln TARGET LINK_NAME when creating a hard link (no -s). TARGET must already exist as a regular file (for normal hard links).
After a successful hard link:
ls -li original.txt hardlink.txt
You should see the same inode number and a link count of at least 2. Editing content through either name changes the same data. Permissions and ownership are properties of the inode—not of each name separately—so chmod on one name affects both.
Rules and limits (exam-critical)
| Rule | Hard link behavior |
|---|---|
| Same filesystem | Required — hard links cannot cross mount points |
| Directories | Normally not allowed for users (ln on a directory fails) |
| After deleting original name | Other hard links still work; data remains |
| Identity | Same inode; not a separate “pointer file” |
# Demonstrate same-filesystem requirement conceptually:
# ln /boot/somefile /home/student/somefile # fails if /boot and /home are different devices
Use df / findmnt to see mount boundaries when a hard link mysteriously fails with “Invalid cross-device link.”
When hard links are useful
- Multiple paths to the same configuration snippet without duplicating content
- Keeping a file alive under a second name while rotating the first name
- Understanding backups and why “delete” is really “unlink this name”
Hard links are less common in modern app packaging than symlinks, but RHCSA still expects you to create and recognize them.
Soft Links (Symbolic Links)
Creating soft links
ln -s target linkname
ln -s /etc/nginx/nginx.conf /home/student/nginx.conf.link
ln -s ../configs/app.conf app.conf
Syntax: ln -s TARGET LINK_NAME. The TARGET is stored as a string inside a new inode of type symlink. The target does not need to exist at creation time—which is both powerful and dangerous.
Inspect:
ls -l linkname
readlink linkname
readlink -f linkname # canonicalize if possible
stat linkname
ls -l shows linkname -> target for symlinks. The first character of the mode string is l. The inode number of the symlink is different from the target’s inode—unlike hard links.
Soft link properties
| Property | Soft link behavior |
|---|---|
| Cross filesystem | Allowed |
| Point to directories | Allowed (and common) |
| Separate inode | Yes — stores path text |
| Broken links | Possible when target path is missing or wrong |
| Permissions | The symlink’s own mode is often not what matters; target permissions apply for content access through the link |
Many tools have options to follow or not follow symlinks (cp -a preserves symlinks; cp -L follows them; ls -L follows; find -type l finds symlinks themselves).
Absolute vs Relative Symlinks (Major Exam Trap)
The string stored in a symlink is either absolute (starts with /) or relative (does not).
Absolute
ln -s /var/www/html/index.html /home/student/index.html
Resolves to the same place regardless of where the symlink lives—until the target path is moved or renamed. If /var/www/html/index.html is relocated, the link breaks even if a file with the same relative layout exists elsewhere.
Relative
cd /home/student/app
ln -s ../data/cache cache
The target string ../data/cache is interpreted relative to the symlink’s directory (/home/student/app), not relative to your shell’s current directory at use time. If you later move the entire app and data tree together, relative links may keep working; absolute links to the old paths will not.
Exam trap: Creating a relative link while your pwd is wrong, or typing a relative path as if it were relative to $PWD at creation without thinking about the link’s final location. Always ls -l the new link and, if needed, readlink -f or cat through the link to verify.
ln -s target.txt /tmp/mylink.txt
# If target.txt was meant relative to /tmp, this stores the literal "target.txt"
# which resolves as /tmp/target.txt — not as $PWD/target.txt unless that was intended.
Create links with explicit absolute targets or carefully computed relative targets from the link’s directory.
Broken Symlinks
A broken (dangling) symlink exists as a directory entry, but its target path does not resolve to an existing object.
Common causes:
- Target file or directory was deleted or renamed
- Absolute path was wrong from the start
- Relative path was computed incorrectly
- Filesystem not mounted (target would be under a mount point that is empty)
Detect:
ls -l # often shows colored dangling links; target still printed after ->
find /path -xtype l
find /path -type l ! -exec test -e {} \; -print
Accessing a broken symlink for content fails (No such file or directory) even though ls lists the link name. Exam trap: Assuming that because ls shows the name, the file content is present—graders may check that the link resolves, not only that a symlink inode exists.
Fix by recreating the link with a correct target, restoring the target object, or removing the bad link and replacing it.
ln Syntax Details Worth Memorizing
ln [-s] TARGET LINK_NAME
ln [-s] TARGET... DIRECTORY # create links inside DIRECTORY
Examples:
ln -s /etc/hosts /tmp/hosts.link
ln -s ../share/data data
ln file.txt /home/student/links/ # hard link named file.txt inside links/
If LINK_NAME already exists as a directory, ln may place a link inside it. If a non-directory name already exists, ln fails unless you force/replace according to options—prefer removing or choosing a free name deliberately.
Useful options:
| Option | Purpose |
|---|---|
-s | Symbolic link |
-f | Force (remove existing destination name) |
-v | Verbose |
-r | With -s, build a relative symlink path (GNU ln) when possible |
Comparing Hard and Soft Links Side by Side
| Aspect | Hard link | Soft link |
|---|---|---|
| Command | ln src dest | ln -s src dest |
| Inode | Same as target | New inode |
ls -l | Normal file entry; higher link count | l.... and -> target |
| Cross-device | No | Yes |
| Directories | Generally no | Yes |
| After removing “original” name | Other hard links still valid | Soft link breaks if path gone |
| Broken state | N/A (each name is equal) | Possible |
Interaction with cp, mv, and rm
rma hard link — removes one name; data remains if link count > 0.rma symlink — removes the symlink inode only; target file is untouched.rmthrough a symlink to a file — depends on what you name; removing the symlink path removes the link, not the target. Removing a file path that is a hard link removes that name.cp -a— preserves symlinks as symlinks.cpwithout care — may follow symlinks and copy target content (double-check withls -lafter copy).mva symlink — moves the symlink object; the stored target string is unchanged (relative links may break if moved to a new directory).
Exam trap: Moving a relative symlink to another directory without updating its target string—../data meant something different from the new parent.
Practical Lab Sequence
mkdir -p /tmp/linklab/{a,b}
echo 'payload' > /tmp/linklab/a/data.txt
ln /tmp/linklab/a/data.txt /tmp/linklab/b/data-hard.txt
ln -s ../a/data.txt /tmp/linklab/b/data-soft.txt
ls -li /tmp/linklab/a/data.txt /tmp/linklab/b/data-hard.txt /tmp/linklab/b/data-soft.txt
cat /tmp/linklab/b/data-soft.txt
rm /tmp/linklab/a/data.txt
ls -l /tmp/linklab/b/
cat /tmp/linklab/b/data-hard.txt # still works
cat /tmp/linklab/b/data-soft.txt # broken relative path now
Walk through why the hard link survived and the soft link did not. That single experiment locks the mental model for the exam.
Common Pitfalls
- Forgetting
-sand accidentally creating a hard link (or failing across devices) - Reversing
lnargument order (target first, link name second—same general idea ascp) - Absolute vs relative confusion producing broken links that “look fine” in
ls - Expecting hard links on directories or across mounts
- Deleting the target of a symlink and not noticing until a service fails to open the path
- Using
cpin a way that replaces a symlink with a regular file copy of the content
Section Checkpoint
You should be able to create hard links with ln and soft links with ln -s, prove hard links via matching inode numbers and elevated link counts, explain why hard links cannot cross filesystems, choose absolute vs relative symlink targets deliberately, find broken symlinks, and predict what happens when names are removed. That understanding prevents subtle file-layout failures on performance tasks.
After ln report.txt report-hard.txt on the same filesystem, which statement is true?
Which limitation applies to hard links but not to symbolic links on a typical RHEL system?
You create ln -s ../data/cache /srv/app/cache while ../data/cache is interpreted relative to the symlink’s directory. What is a common exam risk with this relative link?
How can you most directly confirm that /tmp/mylink is a symbolic link and see the stored target path?