開発マシンのメンテナンスは、やるべきだと分かっていながら後回しにしがちな作業の一つです。
Homebrewのアップデート、Dockerの肥大化したキャッシュ、積み上がったDerivedData——個別には些細でも、放置すれば確実にディスクとパフォーマンスを蝕みます。
本記事では、私が普段使用しているシェルスクリプトを紹介します。
設計方針
メンテナンススクリプトには独特の要件があります。
一部のコマンドが失敗しても、残りは実行を続けてほしい。set -e を使わない理由はここにあります。
set -uo pipefail
-u で未定義変数の参照を防ぎ、pipefail でパイプ中の失敗を検知します。
-e を外すことで、例えば brew doctor が警告を返しても後続の処理は止まりません。
構成
スクリプトは5つのセクションから成ります。
Homebrewの更新とクリーンアップ
brew update && brew upgrade && brew upgrade --cask --greedy
brew cleanup && brew autoremove
brew doctor
--cask --greedy は、自動更新機能を持つアプリ(Chrome、Firefox等)も含めて強制的にアップグレードします。
brew cleanup と brew autoremove で古いバージョンと不要な依存を除去し、brew doctor で環境の整合性を確認します。
Mac App Store
mas upgrade
mas を使い、App Store経由でインストールしたアプリもCLIから更新します。
Xcode関連
xcrun simctl delete unavailable
使われなくなったシミュレータランタイムを削除します。
これだけで数十GBの空きが生まれることもあります。
DerivedDataについては、Xcodeの起動状態を確認してから削除します。
if ! pgrep -q Xcode; then
rm -rf ~/Library/Developer/Xcode/DerivedData/*
fi
ビルドキャッシュを消すだけなので、次回ビルド時に再生成されます。
起動中のXcodeを壊す心配を避けるためのガードです。
パッケージマネージャのキャッシュ整理
npm と pnpm のキャッシュを整理します。
いずれも command -v で存在確認してから実行するため、インストールしていない環境でもエラーにはなりません。
npm cache verify # 整合性チェック。全削除はしない
pnpm store prune # 未参照パッケージの削除
npm cache clean --force ではなく verify を選んでいるのは、壊れたエントリだけを除去し、有効なキャッシュは維持するためです。
Docker クリーンアップ
if command -v docker &>/dev/null && docker info &>/dev/null; then
docker system prune -f --volumes --filter "until=168h"
docker builder prune -f --filter "until=168h"
fi
docker info でデーモンの起動確認を行い、停止中なら何もしません。
--filter "until=168h" により、1週間以内に使用したリソースは保持されます。
直近の作業を壊さない安全策です。
キャッシュ容量の可視化
最後に ~/Library/Caches の上位10ディレクトリを表示します。
du -sh ~/Library/Caches/* 2>/dev/null | sort -rh | head -n 10
自動削除はしません。
アプリケーションキャッシュの削除判断は人間に委ねるべきです。
使い方
適当な場所に保存して実行権限を付与します。
chmod +x ~/scripts/maintenance.sh
手動で定期実行してもいいですし、launchd でスケジュールしても構いません。
ただし、Homebrewやmasは対話的な認証を求めることがあるため、完全な無人実行には向かない点に留意してください。
スクリプト全文
#!/bin/bash
# -------------------------------------------
# エラーハンドリング方針:
# メンテナンススクリプトの性質上、一部失敗しても続行したいため
# set -e は使わず、重要なコマンドのみ個別にハンドリングする。
# 未定義変数の参照とパイプ途中の失敗は検知する。
# -------------------------------------------
set -uo pipefail
# ===========================================
# Homebrewパッケージ更新とクリーンアップ
# ===========================================
brew update && brew upgrade && brew upgrade --cask --greedy
brew cleanup && brew autoremove
brew doctor
# ===========================================
# Mac App Storeアプリのアップデート
# ===========================================
mas upgrade
# ===========================================
# Xcode関連の不要ファイル削除
# ===========================================
xcrun simctl delete unavailable
# Xcodeが起動中でなければDerivedDataを削除
if ! pgrep -q Xcode; then
rm -rf ~/Library/Developer/Xcode/DerivedData/*
else
echo "⚠ Xcodeが起動中のためDerivedDataの削除をスキップしました"
fi
# ===========================================
# パッケージマネージャのキャッシュ/ストア整理
# ===========================================
# npm キャッシュの検証(整合性チェックのみ、全削除はしない)
if command -v npm &>/dev/null; then
echo "--- npm cache verify ---"
npm cache verify
fi
# pnpm ストアの最適化(未参照の依存パッケージを削除)
if command -v pnpm &>/dev/null; then
echo "--- pnpm store prune ---"
pnpm store prune
fi
# ===========================================
# Docker クリーンアップ
# ===========================================
if command -v docker &>/dev/null && docker info &>/dev/null 2>&1; then
echo "--- Docker system prune ---"
# 1週間以上前の未使用リソース + 未使用ボリュームを削除
docker system prune -f --volumes --filter "until=168h"
echo "--- Docker builder prune ---"
docker builder prune -f --filter "until=168h"
fi
# ===========================================
# キャッシュ容量の確認(削除は手動判断)
# ===========================================
echo ""
echo "=== ~/Library/Caches 容量 Top 10 ==="
du -sh ~/Library/Caches/* 2>/dev/null | sort -rh | head -n 10
echo ""
echo "※ 不要なキャッシュがあれば手動で削除してください"
echo " 例: rm -rf ~/Library/Caches/<アプリ名>"
まとめ
このスクリプトが行うのは「安全に削除できるものだけを削除し、判断が必要なものは報告する」ことです。
定型作業を自動化するだけでも、ディスク容量とビルド環境の健全性は改善します。