Reading

用 Brewfile 把新 Mac 的开发环境变成一条命令

换新 Mac 不该靠回忆装软件。brew bundle dump 把整台机器的软件清单固化成一个 Brewfile,新机器上一条命令恢复,再配几行 defaults 固化系统偏好。

返回归档
用 Brewfile 把新 Mac 的开发环境变成一条命令 封面图

适用场景:换新 Mac 或者重装系统后,要花整整一天回忆自己装过什么软件、改过什么设置。用 Homebrew 的 Brewfile 把软件清单固化成一个文件,下次装机基本就是一条命令加一杯茶的时间。

背景和思路

我上次换电脑时的流程是:打开旧电脑的 /Applications 一个个对着看,再翻浏览器下载记录找安装包。花了一天,装完还是缺东西——命令行工具全忘了,用到哪个报错 command not found 才想起来。

其实 Homebrew 自带解决方案:brew bundle。它用一个叫 Brewfile 的清单文件描述这台机器该有什么,正向可以从现有机器导出,反向可以在新机器一键安装。装机从「回忆」变成「执行」。

第一步:从当前机器导出清单

在旧机器(或者现在这台已经配好的机器)上:

brew bundle dump --file=~/dotfiles/Brewfile --describe

--describe 会把每个包的一句话说明写成注释,几个月后回看不会一脸茫然。生成的文件长这样:

# 分布式版本控制系统
brew "git"
# 更快的 grep 替代品
brew "ripgrep"
# JSON 处理器
brew "jq"
# 终端复用
brew "tmux"

cask "visual-studio-code"
cask "orbstack"
cask "raycast"
cask "charles"

# Mac App Store 应用(需要先 brew install mas)
mas "微信", id: 836500024

四种条目对应四类东西:

  • brew:命令行工具;
  • cask:图形界面应用;
  • mas:Mac App Store 应用(配合 mas-cli,要求已登录 App Store);
  • tap:第三方仓库源。

第二步:清单进版本库

Brewfile 是纯文本,放进 dotfiles 仓库跟踪起来:

cd ~/dotfiles
git add Brewfile
git commit -m "chore: 更新软件清单"

以后每装一个新工具,顺手 brew bundle dump --force --describe 刷新清单再提交。清单和现实不一致时,还能用它反向审计:

brew bundle cleanup --file=~/dotfiles/Brewfile

这条命令会列出「装了但不在清单里」的包,加 --force 直接卸载。相当于给这台机器做垃圾清理。

第三步:新机器一键恢复

新 Mac 上先装 Homebrew(官网 https://brew.sh 的一行安装命令),然后:

git clone git@github.com:yourname/dotfiles.git ~/dotfiles
brew bundle install --file=~/dotfiles/Brewfile

剩下的就是等。cask 应用会串行下载安装,几十个应用大概半小时到一小时,期间偶尔要输一次密码。

两个提醒:

  • mas 条目要求先手动登录 App Store,否则会跳过并报错,可以最后单独补跑。
  • cask 的名字偶尔会变(比如曾经的 docker 改叫 docker-desktop),一年以上没跑过的清单先 brew bundle check 看看再执行。

顺手带上系统偏好设置

软件之外,macOS 的系统设置也能脚本化,用 defaults write 固化几个我每台机器必改的项:

#!/usr/bin/env bash
# ~/dotfiles/macos-defaults.sh

# 按住按键重复输入而不是弹出重音菜单
defaults write -g ApplePressAndHoldEnabled -bool false

# 键盘重复速度拉满
defaults write -g KeyRepeat -int 2
defaults write -g InitialKeyRepeat -int 15

# Finder 显示所有扩展名和路径栏
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
defaults write com.apple.finder ShowPathbar -bool true

# 截图存到指定目录,别堆在桌面
mkdir -p ~/Pictures/Screenshots
defaults write com.apple.screencapture location ~/Pictures/Screenshots

killall Finder SystemUIServer

defaults 改的是各应用的 plist,大部分立即生效,个别需要注销。改之前先用 defaults read 记下原值,写错域名或键名不会报错、只会静默无效,所以每加一条都要实际验证一次。

验证

装机完成后跑一遍核对:

brew bundle check --file=~/dotfiles/Brewfile

输出 The Brewfile's dependencies are satisfied. 说明清单全部就位。再抽查几个关键工具的版本:

git --version && node --version && rg --version

收尾检查

  • Brewfile 用 --describe 导出并纳入 dotfiles 版本管理。
  • 每次装新软件后刷新清单,保持清单和现实一致。
  • defaults 脚本里的每一条都在真机上验证过效果。
  • 新机器跑过 brew bundle check 确认收敛。