Friday, September 11, 2026

 

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

  Mac Cleanup Script: Safely Clean Python and Xcode Storage If you use a Mac for Python development, iOS development, or both, storage can g...