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
| Option | Effect |
|---|---|
-s | One summary line per argument |
-h / -k / -m | Human units / kilobytes / megabytes |
-a | List files too, not only directories |
-d N | Only N levels deep |
-c | Append a grand total |
Commands in this lesson
| Command | What it does |
|---|---|
du -sh DIR | Total size of a directory tree, human units. |
du -sh DIR/* | Size of each entry inside DIR. |
du -h -d 1 DIR | Sizes one level deep. |
du -a DIR | Include individual files. |
du -ck A B | Kilobytes for A and B plus a total line. |
du -sk DIR/* | sort -n | Entries ordered by size. |
Quiz
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
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
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
Which option adds a 'total' line when you pass several directories?
- -t
- -c
- -s
- -a
Practice
Write the total human-readable size of `/root/lab/l64` (a single line) into `/root/lab/l64/total.txt`.
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.
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.