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
-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.
Cookies
No adverts, and nothing that follows you to another site. What we set is what signing in
and the forum need. We count page views with Umami, which sets no cookie and identifies nobody. The one exception is Google reCAPTCHA, which checks our forms are being used by
a person, and that one is yours to decline — nothing is loaded from Google until you
say so.
No adverts, and nothing that follows you to another site. We count page views without a cookie and identify nobody. Google reCAPTCHA checks our forms, and that one is yours to decline.
Cookie Policy ·
Privacy Policy