Problem overview
Running out of disk space on macOS can lead to slow performance, application issues, and user frustration. Manually removing temporary files, caches, and outdated downloads is time-consuming. This script automates those cleanup tasks, helping you reclaim valuable storage and enhance overall system health.
#!/bin/bash
# This resource is provided as a convenience for Level users. We cannot
# guarantee it will work in all environments. Please test before deploying
# to your production environment. We welcome contributions to our community
# library
# Level Library
# https://level.io/library/script-macos-disk-cleanup
# Create log file
LOG_FILE="/tmp/cleanup_$(date +%Y%m%d_%H%M).log"
TOTAL_SAVED=0
log_message() {
echo "$1" | tee -a "$LOG_FILE"
}
get_size() {
if [[ -e $1 ]]; then
du -sk "$1" 2>/dev/null | cut -f1
else
echo "0"
fi
}
delete_safely() {
local path="$1"
local desc="$2"
if [[ -e "$path" ]]; then
local size_before=$(get_size "$path")
if rm -rf "$path" 2>/dev/null; then
local freed=$((size_before))
TOTAL_SAVED=$((TOTAL_SAVED + freed))
log_message "Cleaned $desc - Freed $((freed/1024)) MB"
else
log_message "Skipped $desc - Could not delete (may be locked or permission denied)"
fi
fi
}
log_message "Cleanup started at $(date)"
# Clean various temp directories
TEMP_PATHS=(
"/tmp/*"
"/private/tmp/*"
"/private/var/tmp/*"
"$HOME/Library/Caches/*"
"$HOME/Library/Logs/*"
"$HOME/Library/Safari/Downloads/*"
)
log_message "Cleaning temporary files..."
for path in "${TEMP_PATHS[@]}"; do
find "$path" -mindepth 1 -mtime +1 -print0 2>/dev/null | while IFS= read -r -d '' file; do
if [[ ! -f "$file" ]] || lsof "$file" >/dev/null 2>&1; then
continue
fi
delete_safely "$file" "temp file: $(basename "$file")"
done
done
# Clean Downloads folder
log_message "Cleaning Downloads folder..."
if [[ -d "$HOME/Downloads" ]]; then
find "$HOME/Downloads" -mindepth 1 -mtime +30 -print0 2>/dev/null | while IFS= read -r -d '' file; do
if [[ ! -f "$file" ]] || lsof "$file" >/dev/null 2>&1; then
continue
fi
delete_safely "$file" "old download: $(basename "$file")"
done
fi
# Clean Chrome Cache (if Chrome is installed)
if [[ -d "$HOME/Library/Caches/Google/Chrome" ]]; then
log_message "Cleaning Chrome Cache..."
delete_safely "$HOME/Library/Caches/Google/Chrome/Default/Cache/*" "Chrome cache"
fi
# Clean system logs
log_message "Cleaning system logs..."
sudo rm -rf /private/var/log/*.log* 2>/dev/null
sudo rm -rf /private/var/log/asl/*.asl 2>/dev/null
# Clean XCode derived data (if XCode is installed)
if [[ -d "$HOME/Library/Developer/Xcode/DerivedData" ]]; then
log_message "Cleaning XCode derived data..."
delete_safely "$HOME/Library/Developer/Xcode/DerivedData" "XCode derived data"
fi
# Clean App Store cache
log_message "Cleaning App Store cache..."
delete_safely "$HOME/Library/Caches/com.apple.appstore" "App Store cache"
# Final summary
TOTAL_GB=$(echo "scale=2; $TOTAL_SAVED/1024/1024" | bc)
TOTAL_MB=$(echo "scale=2; $TOTAL_SAVED/1024" | bc)
log_message "Cleanup completed at $(date)"
log_message "-------------------------------------------"
log_message "Disk cleanup completed successfully."
log_message "Total space freed: ${TOTAL_MB} MB (${TOTAL_GB} GB)"
log_message "Log file saved to: $LOG_FILE"
log_message "-------------------------------------------"
# Empty trash
log_message "Emptying Trash..."
GUI_USER=$(stat -f '%Su' /dev/console)
USER_HOME=$(dscl . -read /Users/"$GUI_USER" NFSHomeDirectory | awk '{print $2}')
TRASH_PATH="$USER_HOME/.Trash"
if [[ -d "$TRASH_PATH" ]]; then
find "$TRASH_PATH" -mindepth 1 -exec rm -rf {} + 2>/dev/null
log_message "Trash emptied from $TRASH_PATH (user: $GUI_USER)."
else
log_message "Trash folder not found at $TRASH_PATH or already empty (user: $GUI_USER)."
fi
This script searches key locations on macOS—like temporary directories, browser caches, and old download folders—then systematically removes files that are likely no longer needed. It also clears system logs and purges leftover developer data, all while logging its actions for easy review. By targeting files older than a specific age and skipping any that might still be in use, the script ensures a targeted, safe cleanup process that frees up space without risking critical system files.
You can integrate this script into Level for on-demand cleanups. Simply configure a script-based monitor to trigger the script automatically whenever disk space falls below a certain threshold, or use a scheduled automation to run it periodically.
Use cases
- Quick recovery of disk space on macOS endpoints
- Routine cleanup in MSP environments to maintain performance
- Automating maintenance tasks for end-users or project-based systems
- Integrating with Level monitors to proactively clear space when capacity is low
Recommendations
- Test in a non-critical environment before wide deployment
- Set up a script-based monitor in Level to automatically trigger when disk space dips below a threshold
- Schedule periodic cleanups using a Level automation for ongoing maintenance
- Review logs generated in /tmp to confirm proper cleanup
- Customize target folders in the script if your organization stores files in unique locations