this repo has no description
1#!/bin/bash
2# disk-breakdown: generate a visual breakdown of disk usage
3
4set -e
5
6# colors
7BOLD='\033[1m'
8DIM='\033[2m'
9RESET='\033[0m'
10GREEN='\033[32m'
11YELLOW='\033[33m'
12RED='\033[31m'
13
14# get disk info
15read -r SIZE USED AVAIL PERCENT <<< $(df -h /System/Volumes/Data | tail -1 | awk '{print $2, $3, $4, $5}')
16
17# color based on usage
18if [[ ${PERCENT%\%} -gt 90 ]]; then
19 COLOR=$RED
20elif [[ ${PERCENT%\%} -gt 75 ]]; then
21 COLOR=$YELLOW
22else
23 COLOR=$GREEN
24fi
25
26echo ""
27echo -e "${BOLD}DISK: ${SIZE} total | ${COLOR}${USED} used${RESET} ${BOLD}| ${AVAIL} free (${PERCENT})${RESET}"
28echo ""
29
30# bar chart
31BAR_WIDTH=50
32USED_PCT=${PERCENT%\%}
33USED_BARS=$((USED_PCT * BAR_WIDTH / 100))
34FREE_BARS=$((BAR_WIDTH - USED_BARS))
35echo -n "["
36printf "${COLOR}%0.s█${RESET}" $(seq 1 $USED_BARS) 2>/dev/null || true
37printf "${DIM}%0.s░${RESET}" $(seq 1 $FREE_BARS) 2>/dev/null || true
38echo "]"
39echo ""
40
41# home breakdown
42echo -e "${BOLD}~ breakdown:${RESET}"
43dust -d 1 ~ 2>/dev/null | grep -E "^\s*[0-9]+(\.[0-9]+)?[KMGT]?\s" | tail -20
44
45echo ""
46echo -e "${BOLD}other:${RESET}"
47echo " /Applications: $(dust -d 0 /Applications 2>/dev/null | awk '{print $1}')"
48echo " /opt: $(dust -d 0 /opt 2>/dev/null | awk '{print $1}')"
49
50# snapshots
51SNAPS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -c "com.apple" || true)
52if [[ -n "$SNAPS" && "$SNAPS" -gt 0 ]]; then
53 echo ""
54 echo -e "${YELLOW}⚠ $SNAPS APFS snapshot(s) may be holding space${RESET}"
55fi
56
57# pending updates (skip if slow)
58if [[ "${1:-}" != "-q" ]]; then
59 UPDATES=$(timeout 5 softwareupdate -l 2>&1 | grep -c "Label:" || true)
60 if [[ -n "$UPDATES" && "$UPDATES" -gt 0 ]]; then
61 echo -e "${YELLOW}⚠ $UPDATES pending update(s) - install to clear snapshots${RESET}"
62 fi
63fi
64
65# docker check
66DOCKER_RAW="$HOME/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw"
67if [[ -f "$DOCKER_RAW" ]]; then
68 ACTUAL=$(du -sh "$DOCKER_RAW" 2>/dev/null | awk '{print $1}')
69 ALLOC=$(ls -lh "$DOCKER_RAW" 2>/dev/null | awk '{print $5}')
70 echo ""
71 echo -e "${DIM}docker: ${ACTUAL} actual / ${ALLOC} allocated${RESET}"
72fi
73
74# summary
75echo ""
76echo -e "${BOLD}totals:${RESET}"
77APFS_USED=$(diskutil apfs list 2>/dev/null | grep "Capacity In Use" | head -1 | grep -oE '[0-9.]+ GB' | head -1)
78APFS_FREE=$(diskutil apfs list 2>/dev/null | grep "Not Allocated" | head -1 | grep -oE '[0-9.]+ GB' | head -1)
79DATA_VOL=$(diskutil apfs list 2>/dev/null | grep -A3 "Role.*Data" | grep "Capacity Consumed" | grep -oE '[0-9.]+ GB')
80echo " APFS used: $APFS_USED"
81echo " APFS free: $APFS_FREE"
82echo " Data volume: $DATA_VOL"
83
84echo ""
85echo -e "${DIM}$(date '+%Y-%m-%d %H:%M')${RESET}"