Automate Software Installs via Shell Scripts in macOS 13

Automating software installation on macOS 13 (Ventura) eliminates repetitive manual setups and ensures consistent environments across machines. This guide demonstrates how to build a unified shell script using native macOS terminal utilities and Homebrew to automatically install command-line utilities, graphical applications, and direct package files with a single command.


1. Prerequisites and Setup

macOS 13 uses Zsh as the default shell. Before automating package installations, the script must ensure Apple's Command Line Tools and Homebrew are installed, as Homebrew is the industry-standard package manager for macOS.

2. Building the Automation Script

Create a script file named install_software.sh using your preferred text editor. The script follows four distinct steps:

  1. Check and Install Command Line Tools: Required for compiling software and installing Homebrew.
  2. Install Homebrew: Checks if the brew binary exists; if not, installs it non-interactively.
  3. Install CLI Utilities and GUI Apps: Uses brew install for binaries and brew install --cask for full applications.
  4. Install Standalone .pkg Installers (Optional): Uses native macOS commands to handle software not available via package managers.

3. The Complete Installation Script

#!/bin/zsh

set -e # Exit immediately if a command exits with a non-zero status

echo "Starting automated software installation for macOS 13..."

# 1. Install Xcode Command Line Tools if not present
if ! xcode-select -p &>/dev/null; then
    echo "Installing Command Line Tools..."
    touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
    PROD=$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')
    softwareupdate -i "$PROD" --verbose
    rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
else
    echo "Xcode Command Line Tools already installed."
fi

# 2. Check and Install Homebrew
if ! command -v brew &>/dev/null; then
    echo "Installing Homebrew..."
    NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
    # Configure Homebrew path for Apple Silicon or Intel
    if [[ $(uname -m) == 'arm64' ]]; then
        echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
        eval "$(/opt/homebrew/bin/brew shellenv)"
    else
        echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
        eval "$(/usr/local/bin/brew shellenv)"
    fi
else
    echo "Homebrew already installed. Updating recipes..."
    brew update
fi

# 3. Define packages to install
CLI_TOOLS=(
    "git"
    "wget"
    "curl"
    "node"
    "python@3.11"
    "htop"
)

GUI_APPS=(
    "google-chrome"
    "visual-studio-code"
    "iterm2"
    "slack"
    "docker"
)

# 4. Install Command-Line Tools
echo "Installing CLI utilities..."
for tool in "${CLI_TOOLS[@]}"; do
    if brew list "$tool" &>/dev/null; then
        echo "$tool is already installed."
    else
        echo "Installing $tool..."
        brew install "$tool"
    fi
done

# 5. Install GUI Applications via Cask
echo "Installing GUI applications..."
for app in "${GUI_APPS[@]}"; do
    if brew list --cask "$app" &>/dev/null; then
        echo "$app is already installed."
    else
        echo "Installing $app..."
        brew install --cask "$app"
    fi
done

# 6. Clean up
echo "Cleaning up cached installation files..."
brew cleanup

echo "All software successfully installed."

4. Handling Direct .pkg and .dmg Files

If you need to install proprietary software directly without Homebrew, add native macOS installation commands to the script:

  • For .pkg files:

    sudo installer -pkg /path/to/package.pkg -target /
  • For .dmg files:

    hdiutil attach /path/to/installer.dmg
    cp -R "/Volumes/InstallerName/Application.app" /Applications/
    hdiutil detach "/Volumes/InstallerName"

5. Running the Script

  1. Make the script executable by opening Terminal and navigating to the file location:

    chmod +x install_software.sh
  2. Execute the script:

    ./install_software.sh

To deploy this across multiple macOS 13 devices, host the script in a remote Git repository or run it directly through a Mobile Device Management (MDM) solution such as Jamf or Kandji.