Skip to content

Instantly share code, notes, and snippets.

@cPFence
Last active November 28, 2025 10:22
Show Gist options
  • Select an option

  • Save cPFence/d6bb80e77d0bda92c121dd0e8e16e9fc to your computer and use it in GitHub Desktop.

Select an option

Save cPFence/d6bb80e77d0bda92c121dd0e8e16e9fc to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Script by cPFence Team, https://cpfence.app
# Tested on Enhance v12 only!
# Safe Ubuntu cleanup: logs, apt, snap, temp, Docker (no volumes by default)
# Usage: sudo ./safe_cleanup.sh [--with-volumes]
WITH_VOLUMES=0
[[ "${1:-}" == "--with-volumes" ]] && WITH_VOLUMES=1
human() { # bytes to human readable
awk 'function human(x){ s="B K M G T P E Z Y"; while (x>=1024 && s){x/=1024; s=substr(s,3)} printf "%.1f%s", x, substr(s,1,1)} {human($1); }'
}
need_root() {
if [[ $EUID -ne 0 ]]; then
if command -v sudo >/dev/null 2>&1; then
exec sudo -E bash "$0" "$@"
else
echo "Please run as root."
exit 1
fi
fi
}
need_root "$@"
set -o pipefail
log() { printf "\n== %s ==\n" "$*"; }
before_avail=$(df -P -B1 / | awk 'NR==2{print $4}')
log "Starting free space on /: $(df -h / | awk 'NR==2{print $4" free out of "$2}')"
# 1) Journal logs cap
if command -v journalctl >/dev/null 2>&1; then
log "Vacuuming systemd journal to 200M"
journalctl --vacuum-size=200M || true
fi
# 2) Apt caches and orphaned deps
if command -v apt-get >/dev/null 2>&1; then
log "Cleaning apt caches and auto-removing unused packages"
apt-get clean || true
rm -rf /var/cache/apt/archives/* 2>/dev/null || true
apt-get autoremove --purge -y || true
fi
# 3) Snap disabled revisions and cache
if command -v snap >/dev/null 2>&1; then
log "Removing disabled Snap revisions"
snap list --all 2>/dev/null | awk '/disabled/{print $1, $3}' | \
while read -r pkg rev; do snap remove "$pkg" --revision="$rev" || true; done
log "Clearing Snap cache"
rm -rf /var/lib/snapd/cache/* 2>/dev/null || true
fi
# 4) Temp directories
log "Clearing /tmp and /var/tmp"
rm -rf /tmp/* /var/tmp/* 2>/dev/null || true
# 5) Docker prune of unused items
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
log "Docker prune unused containers"
docker container prune -f || true
log "Docker prune unused images"
docker image prune -a -f || true
log "Docker prune build cache"
docker builder prune -a -f || true
if [[ "$WITH_VOLUMES" -eq 1 ]]; then
log "Docker prune unused volumes"
docker volume prune -f || true
fi
fi
# 6) Show top deleted-but-open files hint
if command -v lsof >/dev/null 2>&1; then
log "Deleted but open files over ~50M (restart owning services to free space)"
lsof +L1 2>/dev/null | awk '($7 ~ /^[0-9]+$/ && $7>5e7){printf "%8.0f MB %-15s PID=%-7s %s\n",$7/1024/1024,$1,$2,$9}' | sort -nr | head -10 || true
fi
after_avail=$(df -P -B1 / | awk 'NR==2{print $4}')
freed=$((after_avail - before_avail))
log "Finished. Free space on /: $(df -h / | awk 'NR==2{print $4" free out of "$2}')"
printf "Estimated space reclaimed: %s\n" "$(printf "%s\n" "$freed" | human)"
printf "\nTop space under /var now:\n"
du -xhd1 /var 2>/dev/null | sort -h | tail -10 || true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment