3

Setup

The following sequence of commands is setup for my question.

root@cd330f76096d:/# cd
root@cd330f76096d:~# ls              
root@cd330f76096d:~# mkdir -p my_dir/my_subdir
root@cd330f76096d:~# ls -hAil
total 12K
6175969 -rw-r--r-- 1 root root 3.1K Oct 15  2021 .bashrc
6175970 -rw-r--r-- 1 root root  161 Jul  9  2019 .profile
7382820 drwxr-xr-x 3 root root 4.0K Sep  6 19:34 my_dir

Context

Notice that my_dir has three hard links, as per the output. Presumably they are:

  • ./my_dir
  • my_dir/.
  • my_dir/my_subdir/..

However. . .

root@cd330f76096d:~# find . -xdev -inum 7382820
./my_dir

And that's it. Only one line.

Questions

What am I missing and/or how does ls -l work?

I'm half expecting that the reason why I can't locate any more files with find is that they refer to . and .. in which case I ask how exactly does ls -l work with references to the source code.

Pre setup

The example above was created in a docker container, which for convenience I'm sharing below:

$ docker pull ubuntu:jammy
jammy: Pulling from library/ubuntu
Digest: sha256:aabed3296a3d45cede1dc866a24476c4d7e093aa806263c27ddaadbdce3c1054
Status: Downloaded newer image for ubuntu:jammy
docker.io/library/ubuntu:jammy
$ docker run -it ubuntu:jammy bash
2
  • Does this answer your question? Why does a new directory have a hard link count of 2 before anything is added to it?
    – aviro
    Commented Sep 6, 2023 at 20:12
  • 1
    Is your title supposed phrasing intended to ask how ls finds the link count? It doesn't "find the hard links" as in printing their paths like it does for symlinks (because that's not how "hard links" work). It just gets the count from the stat system call. It's a reference-count for the inode so the kernel (or fsck) can know when to free the inode. Commented Sep 7, 2023 at 9:50

1 Answer 1

4

A pathname that find encounters (i.e., apart from the search paths given on the command line) cannot contain a . or .. component, so your command will never show these.

Why? Because the POSIX standard says so (my emphasis):

Each path operand shall be evaluated unaltered as it was provided, including all trailing <slash> characters; all pathnames for other files encountered in the hierarchy shall consist of the concatenation of the current path operand, a <slash> if the current path operand did not end in one, and the filename relative to the path operand. The relative portion shall contain no dot or dot-dot components, no trailing <slash> characters, and only single <slash> characters between pathname components.

("The current path operand" mentioned above is one of the search paths on the command line.)

The ls command can work out the link count of the directory because it makes a stat() call, which returns a stat structure, which contains the number of hard links. It strictly speaking does not know where the other hard links are located though.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .