Last active
November 28, 2025 10:22
-
-
Save cPFence/d6bb80e77d0bda92c121dd0e8e16e9fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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