Read

Module 7 · The system, disks and the environment

Disk usage: du

df says a filesystem is full; du tells you which directory did it. Summaries, depth limits, totals, and the sort trick that finds the culprit.

What you will learn

  • Measure a directory tree with du -s and du -h.
  • Limit depth and include files with -d and -a.
  • Combine du with sort to find the biggest directories.

df and du are a pair. df asks the filesystem how full it is; du (*disk usage*) walks a directory tree and adds up what each file occupies. When a disk fills up you use df to see *that* it is full and du to see *where* the bytes went.

Summaries and units

Run bare, du DIR prints one line for every subdirectory, deepest first, each with its cumulative size in kilobytes, finishing with the directory itself. On a real tree that is hundreds of lines. Almost always you want -s (summarize: one line per argument) and -h (human units), which together give the classic du -sh DIR. -k and -m force kilobytes or megabytes when you need plain numbers.

~% du /root/lab/l64
4	/root/lab/l64/docs
300	/root/lab/l64/music
700	/root/lab/l64/photos
1004	/root/lab/l64
~% du -sh /root/lab/l64
1004.0K	/root/lab/l64
~% du -sh /root/lab/l64/*
4.0K	/root/lab/l64/docs
300.0K	/root/lab/l64/music
700.0K	/root/lab/l64/photos

That last form, du -sh DIR/*, is the everyday question *what is in here and how big is each piece?* The shell expands the * into one argument per entry and -s gives one line each. Note that * skips hidden names: add .[!.]* if dot-directories might be the problem.

Depth, files and totals

-d N limits the listing to N levels below the start, so du -h -d 1 /var is a tidy table of first-level directories. -a includes individual files, not just directories, which is how you find the single enormous log. -c adds a total line at the end, useful when you pass several directories and want their sum.

~% du -a /root/lab/l64/music
300	/root/lab/l64/music/b.mp3
300	/root/lab/l64/music
~% du -ck /root/lab/l64/photos /root/lab/l64/music
700	/root/lab/l64/photos
300	/root/lab/l64/music
1000	total

Finding the culprit

du prints sizes in the first column and tab-separated paths in the second, which is exactly what sort -n wants. du -sk DIR/* | sort -n lists the entries smallest to largest; add | tail -n 3 for the three biggest. Use -k rather than -h here: GNU sort can order human sizes with sort -h, but BusyBox sort cannot, and 300.0K sorts after 1.2M alphabetically.

~% du -sk /root/lab/l64/* | sort -n | tail -n 1
700	/root/lab/l64/photos
~% du -sk /root/lab/l64/* | sort -n | tail -n 1 | cut -f2
/root/lab/l64/photos
OptionEffect
-sOne summary line per argument
-h / -k / -mHuman units / kilobytes / megabytes
-aList files too, not only directories
-d NOnly N levels deep
-cAppend a grand total

Commands in this lesson

CommandWhat it does
du -sh DIRTotal size of a directory tree, human units.
du -sh DIR/*Size of each entry inside DIR.
du -h -d 1 DIRSizes one level deep.
du -a DIRInclude individual files.
du -ck A BKilobytes for A and B plus a total line.
du -sk DIR/* | sort -nEntries ordered by size.

Quiz

  1. What does `du -sh /var/log` print?

    • One line per file in /var/log
    • A single line with the total size of /var/log in human units
    • The free space of the disk holding /var/log
    • Nothing; -s and -h conflict
  2. Why pipe `du -sk` rather than `du -sh` into sort in this VM?

    • -h is slower
    • BusyBox sort has no -h, so human sizes do not order correctly; plain kilobytes sort with -n
    • sort only accepts tab-separated input with -k
    • There is no difference
  3. ls -l says a file is 1 byte; du says 4.0K. Which is wrong?

    • ls
    • du
    • Neither: du counts allocated blocks and the smallest block is 4 KB
    • Both; the file is corrupt
  4. Which option adds a 'total' line when you pass several directories?

    • -t
    • -c
    • -s
    • -a

Practice

  1. Write the total human-readable size of `/root/lab/l64` (a single line) into `/root/lab/l64/total.txt`.

  2. Find which subdirectory of `/root/lab/l64` is the largest and write its path (just the path) into `/root/lab/l64/biggest.txt`. Do it with a pipeline, not by guessing.

  3. Save the kilobyte sizes of `/root/lab/l64/photos` and `/root/lab/l64/music`, followed by a grand total line, into `/root/lab/l64/both.txt`.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.