Module 10 · Putting it all together
Hard links and symbolic links with ln
Give one file several names with hard links, point at files and directories with symbolic links, and repair links that point nowhere.
What you will learn
- Explain the difference between a file name, an inode and a symbolic link.
- Create hard links with `ln` and symbolic links with `ln -s`.
- Inspect links with `ls -l`, `ls -i` and `readlink`, and repoint them with `ln -sf`.
In lesson 19 you saw that a file is really an inode, a numbered record holding the data, the size and the permissions, and that the name you see in a directory is just a label pointing at that inode. Once you know that, links are easy. A hard link is a second label for the same inode. A symbolic link (symlink) is a tiny separate file whose only content is a path to somewhere else.
Hard links: one file, two names
~% mkdir -p lab/l91 && cd lab/l91
l91% echo "version one" > data.txt
l91% ln data.txt backup.txt
l91% ls -li
6985 -rw-r--r-- 2 root root 12 Oct 7 19:41 backup.txt
6985 -rw-r--r-- 2 root root 12 Oct 7 19:41 data.txt
l91% rm data.txt
l91% cat backup.txt
version one
ln TARGET NAME creates the hard link. ls -i prints the inode number first, and both names show 6985: they are the same file. The number after the permissions, 2, is the link count; it was 1 before. Neither name is the original: edit through one and the other sees the change, and the data only disappears when the last name is removed, which is why cat backup.txt still works after rm data.txt. Hard links have two limits: they cannot point at a directory (ln: hd: Operation not permitted) and they cannot cross from one filesystem to another, because inode numbers are only unique inside one filesystem.
Symbolic links: a signpost
l91% mkdir -p releases/v1 releases/v2
l91% ln -s releases/v2 current
l91% ln -s nowhere.txt broken
l91% ls -l
lrwxrwxrwx 1 root root 11 Oct 7 19:41 broken -> nowhere.txt
lrwxrwxrwx 1 root root 11 Oct 7 19:41 current -> releases/v2
drwxr-xr-x 4 root root 0 Oct 7 19:41 releases
l91% readlink current
releases/v2
l91% readlink -f current
/root/lab/l91/releases/v2
l91% cat broken
cat: can't open 'broken': No such file or directory
ln -s TARGET NAME writes the path TARGET into a new link called NAME. ls -l marks it with an l and shows the arrow. Symlinks can point at directories and at other filesystems, which is why they are used far more often than hard links: /var/spool in this VM is itself a symlink to ../tmp. The price is fragility. The link stores a path, not an inode, so if the target is moved or deleted the link becomes dangling: it still exists, but opening it fails. readlink prints the stored path; readlink -f resolves it all the way to an absolute path.
Repointing a link
ln -s refuses to overwrite an existing name (ln: current: File exists). Add -f to replace it: ln -sf releases/v1 current. When the old link points at a directory, also add -n, so ln treats the link itself as the destination instead of creating a new link inside the directory it points to: ln -sfn releases/v1 current. This one-line switch is how many deployments flip between versions. Removing a link is just rm current; it deletes the link, never the target. Do not add a trailing slash (rm current/), which refers to the directory behind it.
| Hard link | Symbolic link | |
|---|---|---|
| Created with | ln target name | ln -s target name |
| Points to | The inode itself | A path (text) |
| Directories / other filesystems | No / no | Yes / yes |
| If the target is deleted | Data survives | Link dangles |
Seen in ls -l as | A normal file, link count > 1 | l… and name -> target |
In scripts, [ -L path ] is true for a symlink (even a dangling one), while [ -e path ] follows the link and is false when it dangles; together they detect broken links. find /dir -type l lists every symlink below a directory.
Commands in this lesson
| Command | What it does |
|---|---|
ln target name | Hard link: a second name for the same inode. |
ln -s target name | Symbolic link: a small file holding a path. |
ln -sf target name | Replace an existing link. |
ln -sfn dir name | Replace a link that points at a directory. |
ls -li | Show inode numbers and link counts. |
readlink -f name | Resolve a link to its absolute target. |
find /dir -type l | List symbolic links. |
Quiz
`data.txt` has a hard link `backup.txt`. You delete `data.txt`. What happens to the content?
- It is gone; `backup.txt` is now broken.
- It survives and is still reachable as `backup.txt`.
- `rm` refuses because the link count is 2.
Which can point at a directory?
- Only a hard link
- Only a symbolic link
- Both
`ls -l` shows `latest -> v3.conf`, but `cat latest` says `No such file or directory`. Why?
- The link is dangling: `v3.conf` does not exist next to it.
- Symlinks cannot be read with `cat`.
- The link lacks read permission.
What does `readlink -f current` print?
- The link's permissions
- The fully resolved absolute path of the target
- The inode number
How do you tell that two names are hard links to the same file?
- They have the same size.
- `ls -i` shows the same inode number for both.
- `ls -l` shows an arrow between them.
Practice
In `/root/lab/l91` there is `releases/v1` and `releases/v2`. Create a symbolic link `/root/lab/l91/current` that points to `releases/v2`.
Create a **hard** link `/root/lab/l91/backup.txt` for the file `/root/lab/l91/data.txt` (not a copy, not a symlink: both names must share the same inode).
The link `/root/lab/l91/latest` is broken: it points to `v3.conf`, which does not exist. Repoint it to `/root/lab/l91/v2.conf`, replacing the old link.
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.