Mac Cleanup Script: Safely Clean Python and Xcode Storage
If you use a Mac for Python development, iOS development, or both, storage can gradually disappear into caches, build artifacts, and old simulator data.
I created this simple Bash script to check and clean some of the commonly accumulated Python and Xcode development files, while deliberately avoiding deletion of Xcode Archives.
The goal is simple:
Clean up development-related storage without blindly deleting important files.
What This Script Cleans
The script currently checks and cleans the following areas:
Python pip cache
Python packages installed through pip can leave cached files behind.
The script checks:
~/.cache/pip
~/Library/Caches/pip
It uses:
python3 -m pip cache purge
to clear the pip cache when Python 3 is available.
Xcode Derived Data
Xcode generates intermediate build files and other temporary development data under:
~/Library/Developer/Xcode/DerivedData
This directory can become quite large over time.
The script removes the contents of Derived Data:
rm -rf "$DERIVED_DATA"/*
Derived Data is generally rebuildable, so removing it is useful when reclaiming space or troubleshooting build-related issues.
Unavailable iOS Simulators
Xcode can accumulate simulator entries that are no longer available.
The script checks whether simctl is available and then runs:
xcrun simctl delete unavailable
This removes unavailable simulator devices.
What the Script Deliberately Does NOT Delete
One important design choice is that the script does not delete Xcode Archives.
Xcode Archives are stored under:
~/Library/Developer/Xcode/Archives
Archives may contain important application builds, so automatically deleting them could result in losing something that is still needed.
The script therefore only reports their size:
NOTE:
Xcode Archives were NOT deleted.
Archives may contain important app builds.
I prefer this approach over a script that simply searches for large directories and deletes them.
Before-and-After Storage Report
Another useful feature is that the script displays the size of the relevant directories before and after cleanup.
For example:
========== CURRENT STORAGE ==========
Python pip cache:
...
Xcode Derived Data:
...
Xcode Archives:
...
iOS Simulators:
...
After the cleanup, it generates the same report again.
This makes it easy to see whether the cleanup actually recovered meaningful storage.
User Confirmation
The script does not immediately start deleting files.
It asks for confirmation:
read -p "Clean safe caches now? (y/n): " answer
If anything other than y or Y is entered, the script exits:
Cleanup cancelled.
This is a small but important safety mechanism for a script that performs filesystem operations.
Complete Script
Here is the complete version:
#!/bin/bash
# ==========================================
# Mac Python + Xcode Cleanup Script
# ==========================================
echo "=========================================="
echo " MAC CLEANUP - PYTHON & XCODE"
echo "=========================================="
echo ""
# ------------------------------------------
# FUNCTION: Display folder size
# ------------------------------------------
show_size() {
if [ -d "$1" ]; then
du -sh "$1" 2>/dev/null
else
echo "Not found: $1"
fi
}
# ==========================================
# BEFORE CLEANUP - STORAGE REPORT
# ==========================================
echo "========== CURRENT STORAGE =========="
echo ""
echo "Python pip cache:"
show_size "$HOME/.cache/pip"
show_size "$HOME/Library/Caches/pip"
echo ""
echo "Xcode Derived Data:"
show_size "$HOME/Library/Developer/Xcode/DerivedData"
echo ""
echo "Xcode Archives:"
show_size "$HOME/Library/Developer/Xcode/Archives"
echo ""
echo "iOS Simulators:"
show_size "$HOME/Library/Developer/CoreSimulator"
echo ""
echo "=========================================="
echo ""
# ==========================================
# ASK FOR CONFIRMATION
# ==========================================
read -p "Clean safe caches now? (y/n): " answer
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
echo ""
echo "Cleanup cancelled."
exit 0
fi
echo ""
echo "Starting cleanup..."
echo ""
# ==========================================
# PYTHON PIP CACHE
# ==========================================
echo "Cleaning Python pip cache..."
if command -v python3 &> /dev/null; then
python3 -m pip cache purge
else
echo "Python3 not found. Skipping pip cache."
fi
echo ""
# ==========================================
# XCODE DERIVED DATA
# ==========================================
echo "Cleaning Xcode Derived Data..."
DERIVED_DATA="$HOME/Library/Developer/Xcode/DerivedData"
if [ -d "$DERIVED_DATA" ]; then
rm -rf "$DERIVED_DATA"/*
echo "Xcode Derived Data cleaned."
else
echo "Derived Data folder not found."
fi
echo ""
# ==========================================
# REMOVE UNAVAILABLE SIMULATORS
# ==========================================
echo "Removing unavailable iOS simulators..."
if xcrun --find simctl >/dev/null 2>&1; then
xcrun simctl delete unavailable
echo "Unavailable simulators removed."
else
echo "simctl is not available. Skipping simulator cleanup."
fi
# ==========================================
# DO NOT DELETE XCODE ARCHIVES
# ==========================================
echo "NOTE:"
echo "Xcode Archives were NOT deleted."
echo "Archives may contain important app builds."
echo ""
# ==========================================
# AFTER CLEANUP REPORT
# ==========================================
echo "========== STORAGE AFTER CLEANUP =========="
echo ""
echo "Python pip cache:"
show_size "$HOME/.cache/pip"
show_size "$HOME/Library/Caches/pip"
echo ""
echo "Xcode Derived Data:"
show_size "$HOME/Library/Developer/Xcode/DerivedData"
echo ""
echo "Xcode Archives:"
show_size "$HOME/Library/Developer/Xcode/Archives"
echo ""
echo "iOS Simulators:"
show_size "$HOME/Library/Developer/CoreSimulator"
echo ""
echo "=========================================="
echo " CLEANUP COMPLETE"
echo "=========================================="
Clean up log before and after
==========================================
MAC CLEANUP - PYTHON & XCODE
==========================================
========== CURRENT STORAGE ==========
Python pip cache:
Not found: /Users/madhu/.cache/pip
13M /Users/madhu/Library/Caches/pip
Xcode Derived Data:
416M /Users/madhu/Library/Developer/Xcode/DerivedData
Xcode Archives:
Not found: /Users/madhu/Library/Developer/Xcode/Archives
iOS Simulators:
2.5G /Users/madhu/Library/Developer/CoreSimulator
==========================================
Starting cleanup...
Cleaning Python pip cache...
Files removed: 155 (13.5 MB)
Directories removed: 321
Cleaning Xcode Derived Data...
Xcode Derived Data cleaned.
Removing unavailable iOS simulators...
NOTE:
Xcode Archives were NOT deleted.
Archives may contain important app builds.
========== STORAGE AFTER CLEANUP ==========
Python pip cache:
Not found: /Users/madhu/.cache/pip
4.0K /Users/madhu/Library/Caches/pip
Xcode Derived Data:
0B /Users/madhu/Library/Developer/Xcode/DerivedData
Xcode Archives:
Not found: /Users/madhu/Library/Developer/Xcode/Archives
iOS Simulators:
2.5G /Users/madhu/Library/Developer/CoreSimulator
==========================================
CLEANUP COMPLETE
==========================================
How to Use It
Save the script, for example as:
mac-cleanup.sh
Make it executable:
chmod +x mac-cleanup.sh
Then run it:
./mac-cleanup.sh
The script first reports the current storage usage and then asks for confirmation before performing the cleanup.
Why I Kept the Script Conservative
A cleanup script has to balance two things:
Recovering storage
Avoiding accidental deletion of useful development artifacts
For that reason, this script focuses on areas that are intended to be regenerated or are explicitly identified as unavailable simulator data.
I intentionally left Xcode Archives untouched. They can be much more valuable than the storage they consume.
This makes the script more suitable for regular developer-machine maintenance than an aggressive "delete everything related to Xcode" script.
Final Thoughts
Development environments can quietly consume significant disk space over time.
For a Mac used for both Python and Xcode development, periodically checking caches, Derived Data, and obsolete simulator entries can help keep storage under control.
The important principle is not simply to delete large directories.
Know what you are deleting, understand whether it can be regenerated, and protect anything that may contain valuable application artifacts.
No comments:
Post a Comment