Got a new MacBook and thinking about how to set up all the programming languages, packages, and IDEs? The followings scripts help you to automate your macOS setup.
~ 3 minutes read
no time? jump straight to the scripts
Prelude
A macOS setup script is a bash script for me. My script starts with the unofficial-bash-strict-mode and installs the xcode CLI:
set -euo pipefail IFS=$'\n\t' xcode-select --install
I set a SUDO_USER variable as next step, because some of the following installations require sudo :
SUDO_USER=$(whoami)
Package Manager Homebrew
I use Homebrew to install “stuff that I need”. Homebrew is an open source package management system for macOS. The script checks if HomeBrew is installed already. If not, a HomeBrew installation is executed.
if test ! $(which brew); then
/bin/bash -c \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
fi
Next brew step is to upgrade brew and brew formulae with:
brew upgrade
CLI Tools
Get the latest mac CLI tools with:
PROD=$(softwareupdate -l | grep "\*.*Command Line" | head -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | tr -d '\n') || true
if [[ ! -z "$PROD" ]]; then
softwareupdate -i "$PROD" --verbose
fi
GNU utilities and tools
GNU core utilities and GNU tools installation happens with:
brew install coreutils brew install gnu-sed brew install gnu-tar brew install gnu-indent brew install gnu-which brew install findutils
There were changes over time how to install GNU core utilities and tools. (Why was –with-default-names removed? is one example). I follow the brew recommendation to use the commands with their normal names and added the “gnubin” directory to my PATH:
export PATH="/usr/local/opt/findutils/libexec/gnubin:$PATH"
You can find the gnubin recommendation as part of the brew info command for a specific formula e.g.:
$ brew info findutils findutils: stable 4.8.0 (bottled) Collection of GNU find, xargs, and locate https://www.gnu.org/software/findutils/ /usr/local/Cellar/findutils/4.8.0_1 (31 files, 1.8MB) * Poured from bottle on 2021-03-06 at 08:58:14 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/findutils.rb License: GPL-3.0-or-later ==> Caveats All commands have been installed with the prefix "g". If you need to use these commands with their normal names, you can add a "gnubin" directory to your PATH from your bashrc like: PATH="/usr/local/opt/findutils/libexec/gnubin:$PATH" ==> Analytics install: 14,333 (30 days), 55,191 (90 days), 125,336 (365 days) install-on-request: 14,145 (30 days), 54,422 (90 days), 123,262 (365 days) build-error: 0 (30 days)
My find setup is this:
$ find --version find (GNU findutils) 4.8.0 Packaged by Homebrew Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later https://gnu.org/licenses/gpl.html. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Eric B. Decker, James Youngman, and Kevin Dalley. Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2) $ which find /usr/local/opt/findutils/libexec/gnubin/find
JDK installation
Changing the Java version on Mac 11 BigSur was not as straight forward as I initially thought. Thats why is the Java JDK installation a dedicated block of brew formulae.
brew tap AdoptOpenJDK/openjdk brew install --cask adoptopenjdk brew install --cask adoptopenjdk8 brew install --cask adoptopenjdk11 brew install --cask adoptopenjdk14 brew install --cask adoptopenjdk15
Formulae and Casks
With the previous installations and formulae in place, it is now time to install a batch of more formulae.
PACKAGES=(
alfred
...
)
brew install ${PACKAGES[@]}
Casks are extension[s] to Homebrew to install GUI applications such as gimp. I install casks the same way as packages/formulae with the exception of using sudo because it is required by some casks.
CASKS=(
atom
...
)
sudo -u $SUDO_USER brew install --cask ${CASKS[@]}
More Formulae and Casks
My python setup is:
sudo -u $SUDO_USER pip3 install --upgrade pip
sudo -u $SUDO_USER pip3 install --upgrade setuptools
PYTHON_PACKAGES=(
ipython
virtualenv
virtualenvwrapper
)
sudo -u $SUDO_USER pip3 install ${PYTHON_PACKAGES[@]}
Scripts
The script that combines all code snippets above is osx_bootstrap.sh. I use osx_bootstrap_uninstall.sh to uninstall all installations osx_bootstrap.sh creates.
osx_bootstrap.sh
- https://codeberg.org/lotharschulz/gists/src/branch/main/osx_bootstrap.sh
- https://gist.github.com/lotharschulz/304243b8050801f1e9d9af7748b04eb5
osx_bootstrap_uninstall.sh
This script uninstalls formulae and casks installed with osx_bootstrap.sh.
- https://codeberg.org/lotharschulz/gists/src/branch/main/osx_bootstrap_uninstall.sh
- https://gist.github.com/lotharschulz/a6552c5edb4ad032c88d81f4809ae367
osx_bootstrap.sh gist:
DrPsychick commented on Medium:
My reply:
Thanks for sharing your ansible playbook. Ansible is a powerful tool you do a lot of great things with.
I focused on brew and the command line in the context of my write up.
Uzi Landsmann commented on Medium:
My reply:
I see the point of using SDKman when you need a cli tool to easily manage multiple software development kits and its versions.
Almost all macs I observed so far have brew installed because its the missing package manager for macOS.
I use brew regularly because it just works for me.
Please also see this comment which is similar.
Oliver Kriška commented on Medium:
My reply:
Sure, the brew commands can be bundled into a separate Brewfile. However, the check if brew is installed
if test ! $(which brew); then
echo "Installing homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
fi
would not work in a Brewfile, would it?
looks like softwareupdate “-l” doesn’t work the same way in Montery – “MacOS”, not “OS X”. it reports no updates at all and I have not found a magic incantation (yet). Not sure what the results of your PROD= variable assignment should be, or I’d hard-wire it up myself…(hint, hint if you ever see this comment!).
Aside from that, thanks for this page.