Tested script

Find the biggest directories under a path (Bash)

Shows the largest directories directly under a path, biggest first, without crossing into other disks. Use it to drill down step by step when a filesystem fills up.

Tested

The script

#!/usr/bin/env bash
# biggest-dirs.sh: show the largest directories directly under a path.
#
# Usage: biggest-dirs.sh [-n COUNT] [PATH]
#   -n COUNT   how many to show (default 10)
#   PATH       where to look (default: current directory)
#
# Stays on one filesystem (du -x), so a scan of / will not wander into
# network shares or other disks. Read-only.
set -euo pipefail

usage() { sed -n '4,6p' "$0" | sed 's/^# \{0,1\}//'; }

count=10
while getopts ':n:h' opt; do
  case "$opt" in
    n) count="$OPTARG" ;;
    h) usage; exit 0 ;;
    *) usage >&2; exit 2 ;;
  esac
done
shift $((OPTIND - 1))
target="${1:-.}"

if ! [[ "$count" =~ ^[1-9][0-9]*$ ]]; then
  echo "Error: -n must be a positive whole number, got '$count'" >&2
  exit 2
fi
if [[ ! -d "$target" ]]; then
  echo "Error: not a directory: $target" >&2
  exit 1
fi

# du reports unreadable folders on stderr and exits 1; count them, keep going
errfile=$(mktemp)
trap 'rm -f "$errfile"' EXIT

du -x -h --max-depth=1 -- "$target" 2>"$errfile" | sort -rh | head -n "$((count + 1))" || true

skipped=$(wc -l < "$errfile")
if (( skipped > 0 )); then
  echo "Note: $skipped path(s) could not be read (run with more rights to include them)." >&2
fi

Run it

./biggest-dirs.sh /var
./biggest-dirs.sh -n 5 /home

How it works

Options

-n sets how many directories to show, and the path defaults to the current directory. The count must be a positive whole number, and the path must be a directory, or the script exits with an error.

Measure

du -h --max-depth=1 gives one line per subdirectory plus a total for the path itself. -x keeps it on one filesystem, so scanning / does not wander into network mounts or other disks. The -- stops a path that starts with a dash being read as an option.

Sort and trim

sort -rh sorts human-readable sizes like 2.9M and 12G correctly, biggest first. head -n keeps one more line than you asked for, because the total for the path itself is in the list, usually at the top.

Permission errors

Folders you cannot read would clutter the output, so du errors go to a temporary file. wc -l counts them and the script prints one note at the end. A trap deletes the temporary file when the script exits, even on error.