Linux & Bash · Part I · Module 6 · Links and File Identity
Hard Links
[Chapter 6.1](/linux-bash/names-and-inodes) drew two names pointing at one inode and said that arrangement is normal rather than exotic. This chapter creates it on purpose. The command is one word and the behaviour takes about five minutes to verify, but there is an idea inside it that resists being absorbed: once two names point at the same file, there is no original. Not in the sense that it is hard to tell which came first — in the sense that the filesystem does not record it, the two entries are identical in every respect, and the question has no answer. Most explanations of linking skip that, which is why people later find hard links surprising.
Intermediate15 min readLinuxPart IFundamentalsFilesystemLinks
Part I · Module 6 · Chapter 6.2 · Hard Links
1. Making a Second Name
$ ls -li data.txt
83083997 -rw-r--r-- 1 engineer engineer 9 Mar 28 11:20 data.txt
$ ln data.txt also_data.txt
$ ls -li data.txt also_data.txt
83083997 -rw-r--r-- 2 engineer engineer 9 Mar 28 11:20 also_data.txt
83083997 -rw-r--r-- 2 engineer engineer 9 Mar 28 11:20 data.txtRead that output with Chapter 6.1 in hand, because every field is confirming the model:
- the inode numbers are identical —
83083997for both. One file. - the link count went from 1 to 2 — two names now point at that inode.
- every other field matches, because every other field lives in the inode and there is only one inode.
ln is the command, and the form is the same as cp from Chapter 3.2: existing thing first, new name second.
ln EXISTING_NAME NEW_NAMEWhat ln did was add one entry to the directory: the text also_data.txt, paired with the number 83083997. It copied nothing.
2. Nothing Was Copied
Worth dwelling on, because the word "link" suggests something lightweight pointing at something heavy.
$ ls -lh data.txt also_data.txt
-rw-r--r-- 2 engineer engineer 9 Mar 28 11:20 also_data.txt
-rw-r--r-- 2 engineer engineer 9 Mar 28 11:20 data.txtBoth report 9 bytes. That is not 18 bytes of disk used — it is one 9-byte file reported twice, because the size is in the inode and both names reach the same inode.
The new entry costs only the space of a name in a directory. A hard link to a 50 GB file is created instantly and consumes essentially nothing, which is the basis of the real use in §7.
3. Both Names Are Equally Real
Here is the idea that takes some absorbing.
$ cat data.txt
original
$ printf 'changed\n' > also_data.txt
$ cat data.txt
changedWriting through one name changed what the other name shows — because there is one file and both names reach it. No synchronisation happened; there was never anything to synchronise.
Now remove the name that was there first:
$ rm data.txt
$ ls -li also_data.txt
83083997 -rw-r--r-- 1 engineer engineer 8 Mar 28 11:25 also_data.txt
$ cat also_data.txt
changedThe data is intact. The link count dropped from 2 to 1. Chapter 6.1's rule, operating exactly as described: a name was removed, the count decremented, and because it did not reach zero the contents stayed.
This also means ls -l cannot show you that a hard link exists. There is no arrow and no special type character — -rw-r--r-- with a - for an ordinary file, just like everything else. The only visible clue is the link count being greater than 1, which tells you that other names exist and does not tell you where they are.
Finding them is a job for find, which can search by inode number or by sameness with a given file. Module 14 owns that; the point here is that the information is not in the listing.
4. The Three Things a Hard Link Cannot Do
Each restriction follows from Chapter 6.1's model rather than being an arbitrary rule.
It cannot point at a directory
$ mkdir adir
$ ln adir alink
ln: adir: Is a directoryRefused. The reason is that directories form a tree, and .. in each one points back at its single parent. A directory with two parents would break that — .. could not have one correct answer, and it would become possible to build loops that programs walking the tree could never finish.
So the restriction preserves the thing Chapter 2.1 called one tree. Symbolic links in Chapter 6.3 are allowed to point at directories precisely because they work differently.
It cannot cross a filesystem
$ ln data.txt /other_disk/data.txt
ln: /other_disk/data.txt: Invalid cross-device linkChapter 6.1 noted that inode numbers are unique within a filesystem. A directory entry stores a number, and that number only means something to the filesystem it belongs to — entry 83083997 on one disk has nothing to do with entry 83083997 on another.
Chapter 2.1 explained that one tree can span many filesystems through mount points. Two directories that look like neighbours may therefore be on different storage, and a hard link between them is impossible. The error message names the cause directly.
It cannot reach another machine
The same reason, further out. A network filesystem is still one filesystem from the local system's point of view, and a hard link cannot span from it to local storage.
5. Reading the Link Count as a Signal
Chapter 2.5 had you read the third field without being able to interpret it. Now:
$ ls -l
-rw-r--r-- 1 engineer engineer 482 Mar 28 11:40 report.txt
-rw-r--r-- 3 engineer engineer 1024 Mar 28 11:40 shared_data.bin
drwxr-xr-x 4 engineer engineer 4096 Mar 28 11:40 resultsreport.txt, count 1 — one name. The ordinary case, and the overwhelming majority of files.shared_data.bin, count 3 — three names point at this file, somewhere. Deleting this one will not free the space.results, count 4 — a directory, so Chapter 6.1's arithmetic: 2 plus two subdirectories.
That middle line is a genuinely useful signal. A count above 1 on an ordinary file means deleting it will not reclaim its space, because other names remain. On a machine where you are cleaning up to free disk, that is exactly what you need to know before being surprised that nothing changed.
6. Hard Links and the Commands You Know
How earlier chapters' commands behave, all of it following from the model:
| Command | What happens |
|---|---|
rm one_name | removes that entry; the others still work |
mv one_name new_name | renames that entry; the others are unaffected |
chmod, chown | change the inode, so the change is visible through every name |
cp one_name copy | makes a genuinely new file with a new inode — not a link |
| editing in place | visible through every name |
The third and fourth rows are the ones to notice.
chmod 600 also_data.txt changes the permissions seen through data.txt too, because permissions live in the inode and there is one inode. There is no way to give two hard-linked names different permissions.
And cp is not a linking operation. It reads the contents and writes a new file, with a new inode and a link count of 1. Copying a hard link gives you an independent file.
7. What They Are Actually Used For
Hard links are genuinely less common than the symbolic links in Chapter 6.3, and it is worth being honest about that rather than implying you will use them weekly. Two real uses:
Space-efficient snapshots. A backup or release system that keeps many dated copies of a tree can hard-link the files that have not changed between versions. Twenty snapshots of a mostly-unchanging tree then cost roughly the space of one, because the unchanged files have twenty names and one copy of the data.
This is why §5's signal matters: in such a tree, deleting a snapshot frees only the files unique to it, and du will report numbers that look wrong until you remember that shared files are shared.
Replacing a file without a gap. Because a name can be moved onto an existing name atomically, systems that must never be caught mid-update prepare the new version under a temporary name and then move it into place in one step. Readers see either the old file or the new one, never a half-written one.
You are unlikely to build either in Part I. The reason to know them is that you will encounter trees built this way, and the disk arithmetic is inexplicable without the model.
8. The Failures
Expecting ls -l to show them. It cannot. There is no arrow, no l type character, no marker. Only the count hints that other names exist.
Assuming cp preserves the link. It does not. Copying a hard-linked file produces an independent file with its own inode.
Expecting to delete a file by removing one name. If the count is above 1, you have removed a name and freed nothing.
Trying to link a directory, or across filesystems. Both refuse with a clear message — §4. The cross-device one in particular is often the first time somebody discovers that two nearby directories are on different storage.
Thinking one of them is the original. §3. The question has no answer.
9. Why This Matters in Engineering Work
Release and snapshot trees. Large shared project areas frequently use hard links to publish many versions without many copies. Without the model, the space usage is baffling and deleting things appears to achieve nothing.
Cleaning up disk and freeing nothing. Chapter 3.3 and Module 28 are both about reclaiming space. A file with a link count above 1 will not give its space back when you remove one name, and ls -l's third field is the one-second check that explains it.
Knowing when two tool paths are the same program. Chapter 6.1's ls -i comparison. A tool reachable by several names may be one file with several entries, and whether tool and tool-2024.3 are the same file is answered by the inode number.
Part II returns to disk usage and release trees where all three are routine.
10. Practice
Question 1. After ln a.txt b.txt, what is identical between the two names and what is different?
Question 2. What does the link count show before and after that command? What does it show after rm a.txt?
Question 3. You write to b.txt. What does cat a.txt show, and why is no synchronisation involved?
Question 4. Explain why the question "which of these two is the original?" has no answer.
Question 5. Give the three things a hard link cannot do, and the single property of hard links that explains all three.
Question 6. Why are directories excluded? What would break?
Question 7. ls -l shows -rw-r--r-- 3 engineer engineer 2.4G bigfile.dat. You delete it to free space and nothing is freed. Explain.
Question 8. chmod 600 on one of two hard-linked names. What are the permissions seen through the other name, and why?
Question 9. Does cp a.txt c.txt create a third name for the same file? What does it create?
Question 10. A backup directory holds twenty dated snapshots of a project but uses barely more space than one. What is going on?
11. Remember
ln existing newadds a second name for one file. Nothing is copied.- Both names are entirely equal. There is no original, no copy and no marker; the filesystem does not record which came first.
- The inode number is identical and the link count goes up. Those are the two observable facts, and
ls -lishows both. - Writing through one name is visible through the other, because there is one file.
- Removing one name leaves the data, as long as the count has not reached zero.
ls -lcannot show that a hard link exists — only a count above 1 hints that other names are out there. Finding them isfind, in Module 14.- Three restrictions, one cause: no directories (it would break the tree), no crossing filesystems and no spanning machines (an inode number means nothing outside its own filesystem).
- Properties live in the inode, so
chmodandchownthrough one name affect all of them. cpmakes a new file, not another name.- A count above 1 means deleting this name frees no space. That is the practical signal to take away.
Hard links are two names for one thing. The next chapter is the other kind of link — a file whose entire contents are a path written as text, which can point at a directory, cross filesystems, and break in two ways a hard link never can.
Where this fits
Part of the Linux & Bash curriculum.
