Homebrew로 Mac의 모든 소프트웨어 관리하기

2021년 11월 20일 토요일 / ,
简体中文한국어
요약 ·
소프트웨어가 엉망으로 설치되고, 깔끔하게 삭제되지 않으며, 컴퓨터를 바꿀 때마다 다시 설치해야 하는 상황. 그래서 Mac에서 Homebrew에 맡길 수 있는 소프트웨어는 모두 Homebrew에 맡기고, Brewfile 하나에 기록해 두기로 했다.

Mac을 쓰면서 소프트웨어가 점점 뒤죽박죽으로 설치되었다. 어떤 것은 공식 웹사이트에서 내려받은 dmg이고, 어떤 것은 App Store에서 설치했으며, 어떤 것은 Homebrew로 설치한 명령줄 도구이고, 또 어떤 것은 특정 설치 패키지가 끼워 넣은 것이다. 시간이 지나면서 나조차 컴퓨터에 무엇이 설치되어 있는지, 각 소프트웨어가 어디서 왔는지 설명하기 어려워졌다.

소프트웨어 삭제도 골치 아픈 일이다. Mac에서 앱을 삭제할 때 대부분은 휴지통으로 끌어다 넣으면 끝이지만, 그 앱이 ~/Library 아래에 남기는 설정, 캐시, 각종 지원 파일은 함께 삭제되지 않는다. 그래서 컴퓨터를 오래 쓰다 보면 ~/Library 에는 오래전부터 쓰지 않던 소프트웨어가 남긴 것들이 잔뜩 쌓인다. 결국 값비싼 CleanMyMac 같은 도구로 정리하거나, 직접 하나하나 찾아야 한다.

게다가 최근에는 환경을 새 Apple Silicon Mac으로 옮겨야 해서, 예전처럼 하나하나 공식 웹사이트에서 내려받아 다시 설치한다면 너무 힘들 것 같았다. 그래서 앞으로 Mac 소프트웨어는 Homebrew로 설치할 수 있는 것이라면 전부 Homebrew로 설치하고, Brewfile 하나에 모두 기록해 두기로 했다.

Apple Silicon에 Homebrew 설치하기

Homebrew는 3.0부터 Apple Silicon을 네이티브로 지원하며, 설치 명령은 예전과 같다.

Shell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

다만 Intel Mac과 다른 점이 하나 있다. Apple Silicon에서는 Homebrew가 기본적으로 /opt/homebrew에 설치되며, 기존의 /usr/local이 아니다. 그래서 /opt/homebrew/bin 은 기본적으로 PATH 에 들어 있지 않으므로, 설치한 뒤 ~/.zprofile 에 다음 한 줄을 추가해야 한다.

Shell
eval "$(/opt/homebrew/bin/brew shellenv)"

brew shellenv 는 PATH, MANPATH 같은 환경 변수들을 출력하므로, eval 로 실행하면 모두 설정된다.

formula와 cask

Homebrew의 소프트웨어는 두 종류로 나뉜다. formula는 명령줄 도구와 라이브러리, 이를테면 git, ripgrep이고, cask는 그래픽 인터페이스를 갖춘 앱, 예를 들어 Chrome, VS Code이다.

Shell
brew install ripgrep
brew install --cask visual-studio-code

예전에 cask를 설치할 때는 brew cask install을 사용했지만, 작년 말 2.6.0부터 모든 brew cask 명령이 폐기되고, brew 명령에 --cask를 붙이는 방식으로 통일되었다. 그래서 인터넷의 예전 튜토리얼에 있는 표기는 이제 쓸 수 없다.

폰트도 cask로 설치할 수 있지만, 먼저 homebrew/cask-fonts 라는 tap을 추가해야 한다.

Shell
brew tap homebrew/cask-fonts
brew install --cask font-jetbrains-mono

더 깔끔하게 삭제하기

Homebrew로 cask를 관리할 때 큰 장점 중 하나는 삭제다. 일반적인 삭제는 앱 자체만 지우므로 휴지통으로 끌어다 넣는 것과 비슷하다.

Shell
brew uninstall --cask some-app

하지만 --zap 을 붙이면, Homebrew는 cask에 작성된 zap 규칙에 따라 이 앱이 ~/Library 아래에 남긴 환경설정, 캐시, 지원 파일까지 함께 삭제한다.

Shell
brew uninstall --zap --cask some-app

물론 모든 cask에 zap 규칙이 작성되어 있는 것은 아니지만, 자주 쓰는 대부분의 소프트웨어에는 있다. 적어도 내가 직접 ~/Library 를 하나하나 뒤지는 것보다는 훨씬 믿을 만하다.

Brewfile

단순히 Homebrew로 소프트웨어를 설치하기만 한다면, 마이그레이션할 때 여전히 무엇을 설치했는지 직접 기억해야 한다. 다행히 Homebrew에는 bundle 하위 명령이 있어서 현재 설치된 모든 것을 Brewfile로 내보낼 수 있다.

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

--describe 는 각 줄 위에 소프트웨어에 대한 간단한 설명을 한 줄씩 덧붙여 주므로, 나중에 다시 볼 때 낯선 이름을 보고 그게 무슨 역할인지 생각나지 않는 일이 없다. --force 는 기존 파일을 덮어쓴다. 내보낸 Brewfile은 대략 이런 모습이다.

Ruby
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-fonts"
tap "homebrew/core"
# Clone of cat(1) with syntax highlighting and Git integration
brew "bat"
# Modern replacement for 'ls'
brew "exa"
# Simple, fast and user-friendly alternative to find
brew "fd"
# Command-line fuzzy finder written in Go
brew "fzf"
# GitHub command-line tool
brew "gh"
# Search tool like grep and The Silver Searcher
brew "ripgrep"
# Mac App Store command-line interface
brew "mas"
# Password manager that keeps all passwords secure behind one password
cask "1password"
cask "font-jetbrains-mono"
# Web browser
cask "google-chrome"
# Terminal emulator as alternative to Apple's Terminal app
cask "iterm2"
# Control your tools with a few keystrokes
cask "raycast"
# Messaging app with a focus on speed and security
cask "telegram"
# Open-source code editor
cask "visual-studio-code"
mas "Xcode", id: 497799835

마지막 줄의 mas 는 App Store의 명령줄 도구다. 일부 소프트웨어는 Xcode처럼 App Store에만 올라와 있는데, 이런 것도 함께 Brewfile에 적을 수 있으며, 뒤의 숫자는 App Store에서의 ID다.

나는 이 Brewfile을 내 dotfiles 저장소에 넣어 두고, 무엇인가를 설치하거나 삭제할 때마다 다시 dump한 뒤 커밋한다. 이렇게 하면 저장소에는 항상 현재 컴퓨터의 소프트웨어 전체 목록이 남는다.

새 컴퓨터에서 복원하기

새 컴퓨터에서 Homebrew를 설치하고 dotfiles 저장소를 클론한 다음, 명령 한 줄이면 Brewfile에 있는 것들을 전부 다시 설치할 수 있다.

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

이 명령은 tap을 차례로 추가하고 formula와 cask를 설치하며, 이미 설치된 것은 건너뛰므로 중간에 끊겨도 안심하고 다시 실행할 수 있다. cask가 많으면 전체 과정에 시간이 꽤 걸리지만, 그동안은 전혀 신경 쓸 필요가 없어서 하나하나 내려받아 설치하는 것보다 훨씬 편하다.

반대로 정리하기

Brewfile은 설치에만 쓸 수 있는 것이 아니라 반대로 정리하는 데도 쓸 수 있다. brew bundle cleanup 는 컴퓨터에 설치되어 있지만 Brewfile에는 적히지 않은 것들을 나열한다.

Shell
# 只列出来,不删除
brew bundle cleanup --file=~/dotfiles/Brewfile

# 确认没问题之后再真的删除
brew bundle cleanup --force --file=~/dotfiles/Brewfile

그래서 가끔은 반대로 조작한다. Brewfile에서 원하지 않는 소프트웨어를 직접 지운 뒤 cleanup을 한 번 실행하면, 컴퓨터에서도 함께 삭제된다. 이렇게 하면 Brewfile과 컴퓨터 상태를 계속 일치시킬 수 있다.

또한 brew leaves 도 아주 유용한데, 다른 formula가 의존성으로 끌어온 것이 아니라, 내가 직접 설치한 formula만 나열한다. 내가 어떤 도구를 설치했는지 보고 싶을 때 brew list 보다 훨씬 명확하다.

몇 가지 습관

  • cask로 설치할 수 있는 앱은 더 이상 공식 웹사이트에서 dmg를 내려받지 않는다.
  • App Store에만 있는 앱은 mas 로 설치하고, 마찬가지로 Brewfile에 적는다.
  • 소프트웨어를 설치하거나 삭제할 때마다 Brewfile을 한 번 dump하고 커밋한다.
  • 업데이트할 때는 일괄적으로 brew upgrade를 쓰면 cask도 함께 업데이트되며, 스스로 업데이트되는 앱에는 --greedy 를 추가로 붙인다.

이렇게 꾸준히 해 두면 컴퓨터의 소프트웨어에는 모두 출처가 생기고, 컴퓨터를 바꿀 때도 저장소 하나와 명령 한 줄만 있으면 된다. 새 컴퓨터가 도착한 날, 나는 저장소를 클론한 뒤 소프트웨어가 전부 설치될 때까지 거의 다운로드만 기다리고 있었다.

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...