I have found myself needing to set up a machine from scratch and, this time, I’ve decided to write a script to automate setups in future. The full script is on GitHub but I wanted to talk through each step in case others want to do the same.
Execution
I want the script to be executable from a single shell file hosted on GitHub. As GitHub serves static files via the githubusercontent.com domain, the script can be downloaded and immediately run by bash.
bash <(curl -Ls https://raw.githubusercontent.com/phazonoverload/machine-setup/main/setup.sh)At the very top of the script, tell the system to use bash to execute it, and to exit if any command fails.
#!/bin/bashset -eInstall Xcode and Homebrew
XCode comes with a bunch of essential utilities, so we check if it’s installed and install if not. Homebrew will be used later to install lots of software, so also check if it exists, and install it if not. This also runs postinstall commands for Homebrew, and fetches latest repository data.
if xcode-select --install 2>&1 | grep installed; then echo "xcode already installed";else xcode-select --installfi
if test ! $(which brew); then /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/$USER/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"fibrew updateInstall & Configure Git
Install git via Homebrew, configure global settings including git ac which I have in muscle memory for lazy committing-all, generate a new SSH key pair, and make it easy to immediately add to GitHub.
brew install git
echo -n 'Git username: 'read usernamegit config --global user.name "$username"
echo -n 'Git email: 'read mailgit config --global user.email $mail
git config --global alias.ac "!git add -A && git commit -m "
ssh-keygen -t rsacat ~/.ssh/id_rsa.pubopen -a Safari https://github.com/settings/keysread -p "Add public key to GitHub and hit [Enter]."Install Software via Homebrew
Install the GitHub CLI, wget, and mas to later install apps via the Mac App Store.
clis=( 1password-cli gh wget mas yt-dlp ffmpeg)brew install ${clis[@]}Then we install all of the tools with a UI available as a cask:
casks=( 1password arc caffeine camo-studio cleanshot cyberduck cyberghost-vpn discord elgato-camera-hub elgato-control-center elgato-wave-link firefox font-geist-mono google-chrome numi orbstack raycast reflect screen-studio screenflow signal slack todoist vanilla visual-studio-code visual-studio-code@insiders whatsapp zoom)brew install --cask ${casks[@]}And finally cleanup any unused files or caches:
brew cleanupInstall Software via Mac App Store
Some apps are only accessible via the Mac App Store. The first time I wrote this script, I manually installed them and then used mas (installed earlier as a CLI tool with brew) to list existing apps with mas list to reveal the unique IDs for the apps in order to write the lines below:
mas install 1569813296 # 1Password for Safarimas install 682658836 # GarageBandmas install 409201541 # Pagesmas install 409203825 # Numbersmas install 361285480 # Keynotemas install 6475002485 # ReederInstall Node via Volta
I use Volta as my Node version management tool. Grab the latest version of Node, and make it the default.
brew install voltavolta install node@latestvolta setupDownload & Configure Oh My Zsh
I use Zsh as my terminal shell with Oh My Zsh! There’s a couple of manual steps in here because I was too lazy to fully automate editing lines in the default .zshrc but that’s ok! This also downloads the common theme which I like.
curl -L http://install.ohmyz.sh | shwget -O ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/common.zsh-theme https://raw.githubusercontent.com/jackharrisonsherlock/common/master/common.zsh-themeopen ~/.zshrcread -p "Set ZSH_THEME=\"common\" and then [enter]"git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestionsgit clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlightingopen ~/.zshrcread -p "Please add zsh-autosuggestions & zsh-syntax-highlighting to your Plugins! and hit [enter]."chsh -s /usr/local/bin/zshdConfigure Mac Settings
A bunch of macOS settings can actually be done via the terminal.
# Dockdefaults write com.apple.dock "orientation" -string "right"defaults write com.apple.dock "tilesize" -int "24"defaults write com.apple.dock "autohide" -bool "true"defaults write com.apple.dock "show-recents" -bool "false"defaults write com.apple.dock "mineffect" -string "scale"defaults write com.apple.dock "autohide-delay" -float "2"killall Dock# Screenshotsdefaults write com.apple.screencapture "type" -string "png"mkdir -p "$HOME/Pictures/screenshots"defaults write com.apple.screencapture "location" -string "$HOME/Pictures/screenshots" && killall SystemUIServerdefaults write com.apple.screencapture "disable-shadow" -bool "true"# Safaridefaults write com.apple.Safari "ShowFullURLInSmartSearchField" -bool "true" && killall Safari# Finderdefaults write NSGlobalDomain "AppleShowAllExtensions" -bool "true"defaults write com.apple.finder "AppleShowAllFiles" -bool "true"defaults write com.apple.finder "ShowPathbar" -bool "true"defaults write com.apple.finder "FXEnableExtensionChangeWarning" -bool "false"killall Finder# Menu Bardefaults write com.apple.menuextra.clock "DateFormat" -string "\"HH:mm\""# Mission Controldefaults write com.apple.dock "mru-spaces" -bool "false" && killall Dock# Window Managerdefaults write com.apple.WindowManager EnableStandardClickToShowDesktop -bool false && killall WindowManager# Powerdefaults write com.apple.screensaver idleTime 0Last Bits
Because Raycast and VS Code both have excellent settings syncs, they can just be turned on and authenticated and everything snaps back to what it should be. This includes all of my keyboard shortcuts for window management, clipboard management, and AI panels.
In case this falls out of date, the latest version will be on GitHub.