Disks and filesystems
du
Show how much disk space files and directories use, totalled per directory.
du [OPTION...] [FILE...]
du (disk usage) walks a directory tree and reports the space each directory takes, including
everything below it. The everyday forms are du -sh dir for one total and
du -h --max-depth=1 | sort -h to find what is eating a disk.
It measures allocated space, the blocks the filesystem actually set aside, not the byte
count ls shows. The two differ: small files usually occupy a whole block (4 KiB on ext4),
sparse files and compressed filesystems use less than their size, and hard-linked files are
counted once. --apparent-size (or -b) switches to byte counts.
du answers "where did the space go inside this tree"; df answers "how full is the whole
filesystem". When they disagree badly, the usual cause is a deleted file still held open by a
process.
A note on this page's output: the sandbox stores files on a compressed copy-on-write filesystem, and the fixture was copied in moments before each example. Disk usage figures here are therefore small, vary a little between builds, and can be lower than the file size; on a typical ext4 disk every small file would take at least 4.0K.
Examples
Total size of a directory
du -sh data
6.0K data
-s prints one total instead of a line per subdirectory, and -h uses K/M/G units.
Every directory in a tree
du -h
1.0K ./src/lib 3.5K ./src 2.0K ./logs 6.0K ./data 2.0K ./photos 1.5K ./scripts 19K .
Without -s, du prints each directory with the total of everything under it, deepest
first, and finishes with ., the grand total. Files are not listed individually.
Only the first level
du -h --max-depth=1 src
1.0K src/lib 3.5K src
--max-depth=1 (or -d 1) still counts everything, but only prints the top-level
directories. src/lib appears; anything deeper would only count toward it.
Find the biggest items
du -sh -- * | sort -h | tail -4
2.0K logs 2.0K photos 3.5K src 6.0K data
du -sh * gives one total per item in the current directory; sort -h understands the
K/M/G suffixes; tail keeps the largest. The -- protects against a file name starting
with a dash. Dotfiles are not matched by *.
Include individual files
du -ah src
512 src/app.py 512 src/util.sh 512 src/Makefile 512 src/main.c 512 src/lib/helpers.py 1.0K src/lib 3.5K src
-a lists files as well as directories. Small files show tiny figures here, see the note
above.
Bytes in the files versus space on disk
du -sh data
du -sh --apparent-size data
du -sb data
6.0K data 2.1K data 2052 data
The first figure is allocated space, the second the sum of the file sizes, and -b gives
that sum in exact bytes (--apparent-size --block-size=1). Compare du -b with
wc -c or ls -l totals, not with plain du.
A sparse file uses almost no space
truncate -s 1G disk.img
ls -lh disk.img
du -h disk.img
-rw-r--r-- 1 dev dev 1.0G Oct 31 20:19 disk.img 512 disk.img
truncate creates a 1 GiB file without writing any data. ls shows its size, but du
shows the few bytes actually allocated, the reason VM images and databases can look larger
than the disk they live on.
A grand total for several arguments
du -ch logs/*.log
512 logs/app.log 512 logs/error.log 1.0K total
-c adds a total line at the end, handy with a glob. Only app.log and error.log match
*.log; app.log.1 does not end in .log.
Exclude files by pattern
du -sh --apparent-size src
du -sh --apparent-size --exclude='*.py' src
745 src 294 src
--exclude skips files and directories whose names match the pattern. Leaving out the
Python files makes the total smaller.
Stay on one filesystem
du -shx ~
31K /home/dev
-x does not descend into other mounted filesystems. When you scan /, that keeps du out
of /proc, network mounts and other disks.
Directories you cannot read
Setup run before this example
mkdir -p private/inner && chmod 000 privatedu -sh private
du: cannot read directory 'private': Permission denied 512 private
du reports what it cannot enter and exits with 1, but still prints the total it could
measure. Scanning system directories as a normal user produces many of these; add
2>/dev/null to hide them.
Common pitfalls
du -sh *skips dotfiles and directories such as.cachethat are often the biggest. Usedu -sh .[!.]* *ordu -h -d 1 ..Totals from
duanddfwill not match:dfcounts space held by deleted-but-open files, filesystem metadata and reserved blocks.Sorting with
sort -non-houtput puts900Kafter2G. Usesort -h.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
--max-depth=Nis GNU; BSD/macOS uses-d N(GNU accepts-dtoo, sodu -h -d 1works on both).--apparent-size,-b,--exclude,--timeand-t SIZEare GNU options. BSD/macOSduhas-I PATTERNto ignore names; for apparent sizes check its man page (FreeBSD has-A).
Options worth knowing
A selection, described in our own words. For the full list, see du(1) or du --help.
| Option | What it does |
|---|---|
-s, --summarize | Print only a total for each argument. |
-h, --human-readable | Print sizes like 4.0K, 12M, 3.1G. |
-a, --all | Show files too, not just directories. |
-c, --total | Print a grand total at the end. |
-d, --max-depth N | Print totals only N levels deep. |
-x, --one-file-system | Skip directories on other filesystems. |
-b, --bytes | Apparent size in bytes. |
-k | Sizes in 1 KiB blocks (the default unit). |
-m | Sizes in 1 MiB blocks. |
-L, --dereference | Follow all symlinks. |
-t, --threshold SIZE | Show only entries larger than SIZE (or smaller, if negative). |
--apparent-size | Report file sizes rather than disk usage. |
--exclude PATTERN | Skip files matching PATTERN. |
-X, --exclude-from FILE | Skip files matching any pattern in FILE. |
--si | Like -h, but in powers of 1000. |
--time | Show the latest modification time in each directory. |
--inodes | Count inodes instead of space. |
-B, --block-size SIZE | Scale sizes by SIZE, e.g. -BM. |
Related
dfReport how much space is used and free on mounted filesystems.lsList the contents of directories, or the details of individual files.findWalk a directory tree and print, or act on, every file that matches a set of tests.sortSort lines of text alphabetically, numerically, by version or by chosen fields; also merge and de-duplicate.statShow a file's metadata (size, permissions, owner, inode, timestamps), or print chosen fields in your own format.