The number of hard links in ‘ls -l’
When you execute the command ls -l
in UNIX, you get detailed information about files: permissions, file size, date of last modification, etc. A while ago, I got a question from one of my students who wondered what the second column meant. According to the documentation, it’s the “number of hard links,” but what does that actually mean? Let’s get to the bottom of this.
One of my students, Tom, wrote:
I created a directory
test2
containing a file, 3 scripts and another directorytest
containing the same file and scripts. I don’t know whether this is relevant, but I mention it anyway. I created the directorytest2
by copying another directory and copying it within itself (I was playing withcp
).To get back to the number of hard links: when I executed
ls -l
, I saw the number 3 next to directorytest2
. I looked into hard links and noticed that all hard links have the same inode. So I thought, let’s find all hard links oftest2
with thefind / -inum ...
command. However, I only received 1 value:/home/tom/test2
while I expected at least 2 or 3.
So, Tom doubts whether the number in the second column is in fact the number of hard links. The documentation (info ls
) at least confirms this:
'-l'
'--format=long'
'--format=verbose'
In addition to the name of each file, print the file type, file
mode bits, number of hard links, owner name, group name, size, and
timestamp (*note Formatting file timestamps::), normally the
modification time. Print question marks for information that
cannot be determined.
Let’s get to the bottom of this…
Hard links between files
The example below shows that for ordinary files, the second column really is the number of hard links:
$ touch orig
$ ls -li
total 0
1706858 -rw-rw-r--. 1 bert bert 0 Nov 5 21:55 orig
$ ln orig link
$ ls -li
1706858 -rw-rw-r--. 2 bert bert 0 Nov 5 21:55 link
1706858 -rw-rw-r--. 2 bert bert 0 Nov 5 21:55 orig
$ find . -inum 1706858
./orig
./link
When creating the file orig
, the number of hard links was 1. I also added the option -i
to show the inode number. This number uniquely identifies a file. I then created a hard link from the original file. As you can see, both files now have the same inode number and the number of hard links is incremented. Searching on inode number finds both files.
Copying with cp
, as Tom did in his example, creates a new file with the same contents as the original. That means that the inode numbers are also different! Changes in one file will not be registered in the other one. The same goes for symbolic links, in fact:
$ ln -s orig symb
$ ls -il
total 0
1706858 -rw-rw-r--. 2 bert bert 0 Nov 5 21:55 link
1706858 -rw-rw-r--. 2 bert bert 0 Nov 5 21:55 orig
1707044 lrwxrwxrwx. 1 bert bert 4 Nov 5 22:38 symb -> orig
Directories
Now, hard links between directories don’t exist, so the interpretation of the term “number of hard links” is a bit different than with ordinary files. In this case, the number represents how many other directories ‘link to’ it. Specifically, that means the parent directory and all directories immediately below. A new directory starts at “2”, i.e. a link from ‘itself’ and one from the parent directory. The number will increment when you create subdirectories, but not when you create new files or symbolic links.
Take a look at the example below, and try it for yourself. Take your time, I’ll wait…
$ ls -l
total 0
$ mkdir a b
$ ls -l
total 8
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 a
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 b
$ mkdir a/c
$ ls -l
total 8
drwxrwxr-x. 3 bert bert 4096 Nov 5 21:27 a
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 b
$ mkdir a/d
$ ls -l
total 8
drwxrwxr-x. 4 bert bert 4096 Nov 5 21:27 a
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 b
$ touch a/f
$ ls -l
total 8
drwxrwxr-x. 4 bert bert 4096 Nov 5 21:27 a
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 b
$ ln -rs b a/e
$ ls -l
total 8
drwxrwxr-x. 4 bert bert 4096 Nov 5 21:48 a
drwxrwxr-x. 2 bert bert 4096 Nov 5 21:26 b
$ tree -F
.
|-- a/
| |-- c/
| |-- d/
| |-- e -> ../b/
| `-- f
`-- b/
Every time I created a new subdirectory, the number of hard links incremented, but not when creating a file or symbolic link, even to a directory!
As mentioned earlier, creating hard links from directories doesn’t work:
$ ln a c
ln: ‘a’: hard link not allowed for directory
So when Tom was using find to search for a directory test2
based on its inode number, it could necessarily only find it once.
To finish off, let’s look at a corner case, specifically the root directory (/
) of the file system. On my laptop:
$ ls -l /
total 64
lrwxrwxrwx. 1 root root 7 Sep 27 16:37 bin -> usr/bin
dr-xr-xr-x. 5 root root 3072 Oct 29 09:03 boot
drwxr-xr-x. 22 root root 3700 Nov 5 18:33 dev
drwxr-xr-x. 149 root root 12288 Nov 5 18:33 etc
drwxr-xr-x. 4 root root 4096 Jul 8 10:56 home
lrwxrwxrwx. 1 root root 7 Sep 27 16:37 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Sep 27 16:37 lib64 -> usr/lib64
drwx------. 2 root root 16384 Jun 27 19:09 lost+found
drwxr-xr-x. 2 root root 4096 Jul 8 10:56 media
drwxr-xr-x. 3 root root 4096 Jul 8 10:56 mnt
drwxr-xr-x. 4 root root 4096 Sep 27 22:05 opt
dr-xr-xr-x. 263 root root 0 Nov 4 10:28 proc
dr-xr-x---. 5 root root 4096 Nov 3 02:32 root
drwxr-xr-x. 37 root root 1120 Nov 5 21:46 run
lrwxrwxrwx. 1 root root 8 Sep 27 16:37 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 Jul 8 10:56 srv
dr-xr-xr-x. 13 root root 0 Nov 4 09:28 sys
drwxrwxrwt. 16 root root 420 Nov 5 21:46 tmp
drwxr-xr-x. 13 root root 4096 Sep 27 16:37 usr
drwxr-xr-x. 21 root root 4096 Sep 27 16:39 var
$ ls -ld /
dr-xr-xr-x. 18 root root 4096 Nov 4 09:29 /
As you can see in the last line, the number of hard links of /
is 18. When you count the number of subdirectories directly below /
(not counting symbolic links like /sbin -> /usr/sbin
), you get 16. Adding the directory’s “own” hard link, you would expect the final number to be 17 because /
is at the top of the directory hierarchy, right? But let’s try this:
$ cd ..; pwd
/
$ cd ..; pwd
/
$ cd ..; pwd
/
...
Turtles all the way up! So apparently, the root directory is its own parent directory! And consequently, the number 18 is right after all…
Thank you, Tom, for the interesting question!
(I wrote and published this post elsewhere at first, but I’m consolidating everything that is worth preserving on this site.)