💻
Mac起動時にHomebrewを自動更新・アップグレードする方法
Mac起動時にHomebrewを自動更新・アップグレードする方法
はじめに
Macのパッケージ管理でよく使う Homebrew 。
毎回手動で brew update や brew upgrade を実行するのは手間だと感じて、「Macを起動するたびに自動で Homebrew の更新ができたら便利なのに…」と思った。
そこで今回は、Macの起動時や特定の曜日にHomebrewの更新を自動実行する方法 を紹介する。
解決する方法はいくつかある
1. .zshrc に書く
最もシンプルな方法。
ターミナルを開くたびに自動でコマンドが実行される。
# ~/.zshrc
/opt/homebrew/bin/brew update
ただし「起動時だけ」ではなく ターミナルを開くたび に走る。
そのため、今回の用途にはやや不向き。
2. Automator を使う
GUIでスクリプトを作成し、ログイン項目に登録する方法。
- Automator を開いて「新規アプリケーション」を作成する
- 「シェルスクリプトを実行」を追加する
- 中に以下を記述する
#!/bin/zsh
/opt/homebrew/bin/brew update && /opt/homebrew/bin/brew upgrade
-
brew-updater.appのような名前で保存する - システム設定 → 一般 → ログイン項目 に追加する
起動時に一度だけ実行できるが、細かいスケジューリングはできない。
3. launchd(plist)を使う
macOS 標準のジョブスケジューラ。
起動時・曜日・時間など柔軟に指定できる。
例えば、平日は brew update、日曜は brew upgrade というように細かく分けられる。
launchd + plist で問題解決
1. 平日の brew update
-
~/Library/LaunchAgents/com.user.brewupdate.plistを作成する - 以下の内容を記述する
- 平日9時に
brew updateを実行する- StartCalendarInterval で曜日と時間を指定
-
Weekdayは月曜が1、火曜が2、…、日曜が0または7
- ログは
/tmp/brewupdate.logと/tmp/brewupdate.errに出力する- 一時的なログなので
/tmpに保存する - 再起動で消えるので容量を圧迫しない
- もし永続化したい場合は
~/Library/Logs/などに変更する
- 一時的なログなので
- シェルは
zshを指定する -
brewのフルパスを指定する(which brewで確認)
- 平日9時に
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ジョブのラベル名(任意の一意名) -->
<key>Label</key>
<string>com.user.brewupdate</string>
<!-- 実行するコマンド(zsh経由でbrew update) -->
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>/opt/homebrew/bin/brew update</string>
</array>
<!-- 平日9時に実行するスケジュール -->
<key>StartCalendarInterval</key>
<array>
<dict><key>Weekday</key><integer>1</integer><key>Hour</key><integer>9</integer></dict>
<dict><key>Weekday</key><integer>2</integer><key>Hour</key><integer>9</integer></dict>
<dict><key>Weekday</key><integer>3</integer><key>Hour</key><integer>9</integer></dict>
<dict><key>Weekday</key><integer>4</integer><key>Hour</key><integer>9</integer></dict>
<dict><key>Weekday</key><integer>5</integer><key>Hour</key><integer>9</integer></dict>
</array>
<!-- 標準出力・標準エラーのログ出力先 -->
<key>StandardOutPath</key><string>/tmp/brewupdate.log</string>
<key>StandardErrorPath</key><string>/tmp/brewupdate.err</string>
</dict>
</plist>
2. 日曜の brew upgrade
-
~/Library/LaunchAgents/com.user.brewupgrade.plistを作成する - 以下の内容を記述する
- 日曜9時に
brew upgradeとbrew cleanupを実行する- StartCalendarInterval の
Weekdayは日曜が0または7 -
brew upgradeの後にbrew cleanupを実行して、古いバージョンを削除する
- StartCalendarInterval の
- ログは
/tmp/brewupgrade.logと/tmp/brewupgrade.errに出力する- 一時的なログなので
/tmpに保存する - 再起動で消えるので容量を圧迫しない
- もし永続化したい場合は
~/Library/Logs/などに変更する
- 一時的なログなので
- シェルは
zshを指定する -
brewのフルパスを指定する(which brewで確認)
- 日曜9時に
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ジョブのラベル名(任意の一意名) -->
<key>Label</key>
<string>com.user.brewupgrade</string>
<!-- 実行するコマンド(zsh経由でbrew upgrade & cleanup) -->
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>/opt/homebrew/bin/brew upgrade && /opt/homebrew/bin/brew cleanup</string>
</array>
<!-- 日曜9時に実行するスケジュール -->
<key>StartCalendarInterval</key>
<dict>
<key>Weekday</key><integer>0</integer>
<key>Hour</key><integer>9</integer>
</dict>
<!-- 標準出力・標準エラーのログ出力先 -->
<key>StandardOutPath</key><string>/tmp/brewupgrade.log</string>
<key>StandardErrorPath</key><string>/tmp/brewupgrade.err</string>
</dict>
</plist>
3. 設定の有効化
ターミナルで以下を実行する
-
~/Library/LaunchAgents/にplistを保存したら、launchctl loadコマンドで登録する。- これでMac起動時にplistが読み込まれ、指定したスケジュールでコマンドが実行されるようになる。
- 注意点
-
launchctl loadコマンドはエージェント(plist)をmacOSに登録する-
launchctl loadは、指定したplistファイルをmacOSに登録し、スケジュールや条件に従って自動実行できるようにする。 - ただし、
loadした時点では即座にコマンドが実行されるわけではなく、plistで指定したタイミング(例:平日9時、日曜9時)に自動で実行される。 - そのため、コマンド自体が即座に
brew updateやbrew upgradeを実行するわけではない。
-
- 実際のコマンド実行は、plistで指定したスケジュール(例:平日9時、日曜9時)になったタイミングで自動的に行われる。
- 登録直後にすぐ実行したい場合は、
launchctl start com.user.brewupdateのようにLabel名を指定して手動実行も可能。- 例えば
launchctl start com.user.brewupdateのように、plist内のLabel名を指定する。 - スケジュールを待たずに動作確認したい場合や、すぐにコマンドを実行したい場合に便利。
- 例えば
-
launchctl load ~/Library/LaunchAgents/com.user.brewupdate.plist
launchctl load ~/Library/LaunchAgents/com.user.brewupgrade.plist
これで 平日は brew update、日曜は brew upgrade が自動実行される。
リスクについて
自動化は便利ですが、注意も必要。
-
起動遅延:
brew upgradeは数分かかることもある - 破壊的アップデート: major バージョンアップで環境が壊れる可能性もある
-
ストレージ圧迫: 古いバージョンが溜まる場合がある(
brew cleanupで対策) - 失敗の見落とし: ログ確認を忘れるとトラブルに気づきにくい
plistを解除する方法
不要になった場合は unload で無効化できる。
launchctl unload ~/Library/LaunchAgents/com.user.brewupdate.plist
launchctl unload ~/Library/LaunchAgents/com.user.brewupgrade.plist
完全に削除する場合は以下のように実行する。
rm ~/Library/LaunchAgents/com.user.brewupdate.plist
rm ~/Library/LaunchAgents/com.user.brewupgrade.plist
まとめ
-
.zshrc→ ターミナル起動ごとに実行する - Automator → 起動時に1回だけ実行する
-
launchd(plist) → 起動時・曜日・時間など柔軟にスケジュール可能
今回のように「平日は update、日曜に upgrade」といった細かい制御をしたい場合は、macOS標準機能の launchd を使うことで追加インストール不要で、細かいスケジューリングも柔軟にできるのでベスト。
Discussion