Linux commands
ls command
directory sizes
system administration
file management

Using ls to list directories and their total sizes

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The ls command does not calculate total directory sizes. It shows the directory entry size (typically 4 KB on ext4), not the sum of all files inside. To list directories with their actual total sizes, you need du (disk usage). This article covers every practical approach, from the simplest one-liner to cross-platform alternatives on macOS and scripted solutions.

Why ls -lh Shows the Wrong Size

When you run ls -lh, directories appear as 4.0K (or 4096 bytes). This is the size of the directory metadata block, not the contents:

bash
$ ls -lh /var/log
drwxr-xr-x  2 root root 4.0K Jun 10 08:00 apt
drwxr-xr-x  2 root root 4.0K Jun 10 08:00 nginx

Both show 4.0K regardless of whether they contain 1 MB or 10 GB of log files. The directory entry only stores filenames and inode pointers, so its on-disk size has nothing to do with the total size of the files it contains.

The Standard Approach: du

Show Total Size of Each Directory

bash
du -sh */
  • -s : summarize (show only the total for each argument, not every subdirectory)
  • -h : human-readable sizes (K, M, G)
  • */ : glob that matches only directories

Example output:

 
11.2G    projects/
2340M    downloads/
356K     scripts/
44.0G    docker-data/

Sort by Size (Largest First)

bash
du -sh */ | sort -rh

sort -rh sorts in reverse (-r) human-readable (-h) order, so the largest directories appear at the top.

Include Hidden Directories

The */ glob skips dotfiles. To include them:

bash
du -sh .[^.]* */ 2>/dev/null | sort -rh

.[^.]* matches names starting with a dot but excludes . and ... The 2>/dev/null suppresses errors for non-existent matches.

Limit Depth

Show sizes for directories only one level deep (do not recurse into subdirectories):

bash
du -h --max-depth=1 /var | sort -rh

On macOS, the flag is -d instead of --max-depth:

bash
du -h -d 1 /var | sort -rh

Show Top 10 Largest Directories

bash
du -sh */ | sort -rh | head -10

The ncdu Interactive Browser

For regular disk-space audits, ncdu (NCurses Disk Usage) provides an interactive, navigable interface:

bash
1# Install
2sudo apt install ncdu        # Debian/Ubuntu
3sudo yum install ncdu        # RHEL/CentOS
4brew install ncdu            # macOS
5
6# Run
7ncdu /home

ncdu scans the directory tree once, then lets you navigate, sort, and even delete files from within the UI. It is significantly faster for exploring large trees than repeatedly running du.

macOS-Specific Notes

macOS ships a BSD version of du that differs from the GNU version on Linux:

FeatureGNU du (Linux)BSD du (macOS)
Human-readable-h-h
Max depth--max-depth=N-d N
Apparent size--apparent-sizeNot available
Exclude pattern--exclude=PATTERN-I PATTERN
Block size units1K blocks by default512-byte blocks by default

To get GNU behavior on macOS, install coreutils via Homebrew:

bash
brew install coreutils
# GNU du is available as 'gdu'
gdu -sh --max-depth=1 /Users

Combining du with Other Commands

Find Directories Over a Threshold

List directories larger than 1 GB:

bash
du -sh */ | awk '$1 ~ /G/ && $1+0 > 1'

Export to CSV

bash
du -sb */ | awk -F'\t' '{printf "%s,%s\n", $2, $1}' > directory_sizes.csv

-b gives sizes in bytes (GNU only), which is easier to parse programmatically.

Watch for Growth Over Time

bash
1# Save a baseline
2du -sb */ > /tmp/sizes_baseline.txt
3
4# Later, compare
5du -sb */ > /tmp/sizes_current.txt
6diff /tmp/sizes_baseline.txt /tmp/sizes_current.txt

Command Reference Table

CommandWhat It Does
du -sh */Total size of each directory, human-readable
du -sh */ | sort -rhSame, sorted largest first
du -h --max-depth=1 .Sizes one level deep (GNU)
du -h -d 1 .Sizes one level deep (macOS BSD)
du -sh .[^.]* */Include hidden directories
du -sb */Sizes in bytes (for scripting)
ncdu /pathInteractive disk usage browser
df -hFree space per mounted filesystem

Common Pitfalls

  • Using ls -l and trusting the size column for directories. That column shows the directory entry size, not the total contents. Always use du.
  • Forgetting --max-depth on large trees. Running du -sh / without a depth limit will traverse the entire filesystem and can take minutes.
  • Permission errors skewing totals. If du cannot read a subdirectory, it silently skips it, and the reported total will be smaller than reality. Run with sudo for accurate system-wide audits.
  • Hard links being double-counted. By default, du counts each hard link separately. Use du -l (GNU) to count all links, or the default behavior which counts each file once regardless of link count, depending on your version.
  • macOS vs. Linux flag differences. Scripts written for GNU du will fail on macOS. Use the compatibility table above or install coreutils.

Summary

  • ls does not and cannot show total directory sizes. Use du instead.
  • du -sh */ | sort -rh is the most common one-liner for listing directories sorted by size.
  • Use --max-depth=1 (Linux) or -d 1 (macOS) to limit recursion depth.
  • For interactive exploration, install ncdu.
  • On macOS, be aware that du flags differ from GNU/Linux. Install coreutils for consistent behavior.

Course illustration
Course illustration

All Rights Reserved.