Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We have two directories:

$ ls -l
total 8
drwxr-x--- 2 nimmy nimmy 4096 Nov 15 19:42 jeter
drwxr-x--- 2 nimmy nimmy 4096 Nov 15 19:42 mariano

I create one file in the first folder:

$ dd if=/dev/zero of=jeter/zero_file.1 bs=512000 count=1
1+0 records in
1+0 records out
512000 bytes (512 kB) copied, 0.268523 s, 1.9 MB/s

This is the output of du:

$ du -sh *
504K    jeter
4.0K    mariano

As expected, if I place a hard link of the zero_file. in the other folder du output does not change:

$ ln jeter/zero_file.1 mariano/zero_file.2
$ du -sh *
504K    jeter
4.0K    mariano

However, as far as I'm aware, there is nothing in the filesystem that points to zero_file.1 as the original file. So how does du know to count zero_file.1 but not zero_file.2?

It cannot be a timestamp comparison because all hard links share one inode; they'll have the same timestamp data correct?

share|improve this question
up vote 10 down vote accepted

Extending your test to three folders, you can see that only the first time the inode is hit does du count it. If you go into the individual folder and run du, you'll get the full size.

To test:

mkdir alexandru
ln mariano/zero_file.2 alexandru/zero_file.0
du -sh *

You should now see alexandru taking up the 500K+. So without looking at the du code, I'm guessing it stores a list of traversed inodes and doesn't revisit the ones already seen.

share|improve this answer
I see. So it traverses the directories alphabetically and keeps track of seen inodes. At least that's what further testing on my side conclude. – Belmin Fernandez Nov 16 '10 at 2:15
I believe that du only traverses directories alphabetically in the cases above because that is the way that the glob expands the wildcard *. I could be wrong about this, but I don't recommend counting on the order being alphabetical. – Slartibartfast Nov 16 '10 at 5:12
@Slartibartfast you are correct, running ls | sort -r | xargs du -hs shows the last folder as being 500 K. So it does track inodes in the order it sees them, whether that's alphabetical or otherwise. – roguesys Nov 16 '10 at 5:42

If you do

du -sh jeter jeter mariano

Then you get 2 different sizes for jeter.

This seems to be in keeping with the finding above...

... except shouldn't the 1st value be the total and the 2nd value be zero?

share|improve this answer
Although weird, that's consistent with Dennis Williamson's first POSIX quote, which states that the inode is only remembered for "files with multiple links", implying that files that have only a single (hard) link will be counted every time the directory is included, while those with multiple links will only be counted the first time. +1 for finding an interesting edge case. – Dave Sherohman Nov 22 '10 at 7:07

Apparently, when fstat(3) sees that the number of hard links is greater than one, it records the inode number for subsequent matching. According to POSIX:

Files with multiple links shall be counted and written for only one entry. The directory entry that is selected in the report is unspecified.

The shell expands the * glob in lexical order, according to POSIX:

If the pattern matches any existing filenames or pathnames, the pattern shall be replaced with those filenames and pathnames, sorted according to the collating sequence in effect in the current locale.

However, when du -sh is done without globbing, the order has to be decided in some way, but it sounds like it must be implementation dependent.

Note that these two commands give different results:

du -sh jeter mariano
du -sh mariano jeter
share|improve this answer
When du -sh is done without globbing, the user (caller) will have decided on the order that they provided the arguments. (e.g., jeter mariano or mariano jeter) When it's done with globbing the order is still not decided by du itself, it's decided by the shell, as per your second quoted POSIX passage. – Dave Sherohman Nov 22 '10 at 7:04

If you want to check whether or not your backup from rsync time machine work, and possibly more important how much backup space you are saving, you should do a ls -cr | xargs du -hs which will feed the directories to du in the correct sequence (reversed time of creation).

share|improve this answer
This is not an answer to this question. And ls -c sorts by inode change time, not create time (which is generally not stored). – Scott Jun 13 '14 at 15:15

You must log in to answer this question.

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