7

The default behavior of du on my system is not the proper default behavior.

If I ls my /data folder, I see (removing the stuff that isn't important):

ghs
ghsb -> ghs
hope
rssf -> roper
roper

Inside each folder is a set of folders with numbers as names. I want to get the total size of all folders named 14, so I use:

du -s /data/*/14

And I see...

161176 /data/ghs/14
161176 /data/ghsb/14
8 /data/hope/14
681564 /data/rssf/14
681564 /data/roper/14

What I want is only:

161176 /data/ghs/14
8 /data/hope/14
681564 /data/roper/14

I do not want to see the symbolic links. I've tried -L, -D, -S, etc. I always get the symbolic links. Is there a way to remove them?

13

This isn't du resolving the symbolic links; it's your shell.

* is a shell glob; it is expanded by the shell before running any command. Thus in effect, the command you're running is:

du -s /data/ghs/14 /data/ghsb/14 /data/hope/14 /data/rssf/14 /data/roper/14

If your shell is bash, you don't have a way to tell it not to expand symlinks. However you can use find (GNU version) instead:

find /data -mindepth 2 -maxdepth 2 -type d -name 14 -exec du -s {} +
  • Works perfectly. Can someone explain the use of {} and + here? – Victor Wong Mar 22 at 2:30
1

Make du skip symbolic links:

du isn't smart enough to not chase links. By default find will skip symlinks. So creating an unholy alliance between find, du, awk and cat, the proper dark magic incantation becomes:

find /home/somedirectory/ -exec du -s {} + >| /tmp/tmp.txt; cat tmp.txt | awk '{total = total + $1}END{print total}'

Produces:

145070492

To force the output to be human readable:

find /home/somedirectory/ -exec du -s {} + >| /tmp/tmp.txt; cat tmp.txt | awk '{total = total + $1}END{print total}' | awk '{ foo = $1 / 1024 / 1024 ; print foo "MB" }'

Produces:

138.35MB

What's going on here:

/home/somedirectory/      directory to search.
-exec du -s               for each result run a du -s producing bytes
+ >| /tmp/tmp.txt         alliance between find and du, force overwrite tmp.txt
first awk '...'           get the first token of every line and add them up
second awk '...'          take the number and divide by 1024 twice to produce MB
  • should be cat /tmp/tmp.txt – Gu Wang Apr 26 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.