💻

Mac起動時にHomebrewを自動更新・アップグレードする方法

に公開

Mac起動時にHomebrewを自動更新・アップグレードする方法

はじめに

Macのパッケージ管理でよく使う Homebrew
毎回手動で brew updatebrew upgrade を実行するのは手間だと感じて、「Macを起動するたびに自動で Homebrew の更新ができたら便利なのに…」と思った。

そこで今回は、Macの起動時や特定の曜日にHomebrewの更新を自動実行する方法 を紹介する。


解決する方法はいくつかある

1. .zshrc に書く

最もシンプルな方法。
ターミナルを開くたびに自動でコマンドが実行される。

# ~/.zshrc
/opt/homebrew/bin/brew update

ただし「起動時だけ」ではなく ターミナルを開くたび に走る。
そのため、今回の用途にはやや不向き。


2. Automator を使う

GUIでスクリプトを作成し、ログイン項目に登録する方法。

  1. Automator を開いて「新規アプリケーション」を作成する
  2. 「シェルスクリプトを実行」を追加する
  3. 中に以下を記述する
#!/bin/zsh
/opt/homebrew/bin/brew update && /opt/homebrew/bin/brew upgrade
  1. brew-updater.app のような名前で保存する
  2. システム設定 → 一般 → ログイン項目 に追加する

起動時に一度だけ実行できるが、細かいスケジューリングはできない。


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 で確認)
<?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 upgradebrew cleanup を実行する
      • StartCalendarInterval の Weekday は日曜が 0 または 7
      • brew upgrade の後に brew cleanup を実行して、古いバージョンを削除する
    • ログは /tmp/brewupgrade.log/tmp/brewupgrade.err に出力する
      • 一時的なログなので /tmp に保存する
      • 再起動で消えるので容量を圧迫しない
      • もし永続化したい場合は ~/Library/Logs/ などに変更する
    • シェルは zsh を指定する
    • brew のフルパスを指定する(which brew で確認)
<?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 updatebrew 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