From 06b2b6200067f1b2e590fc996fbe69ff4b01a673 Mon Sep 17 00:00:00 2001 From: Marcelo Silveira Date: Fri, 18 Sep 2026 07:40:24 -0300 Subject: [PATCH] Prime sudo before running the Homebrew installer On a freshly booted macOS machine the bootstrap aborted with: ==> Checking for `sudo` access (which may request your password)... Need sudo access on macOS (e.g. the user mhfs needs to be an Administrator)! error: Homebrew installation failed The user is an administrator; the message is a red herring. We run the Homebrew installer with NONINTERACTIVE=1, and its have_sudo_access() adds `-n` to sudo whenever that variable is set: elif [[ -n "${NONINTERACTIVE-}" ]] then SUDO+=("-n") so its pre-flight `sudo -l mkdir` check can never prompt. With no cached sudo timestamp yet, it fails and the installer aborts. Prime the timestamp ourselves first with a prompt-capable `sudo -v`. The installer's privileged commands go through execute_sudo, which calls /usr/bin/sudo without `-n`, so they re-prompt on their own if the timestamp expires during the Command Line Tools download later in the run; only the pre-flight check needed priming. Also drop the "sudo will ask for your password" line that preceded the installer, since NONINTERACTIVE=1 is exactly what stopped it from asking. The replacement is printed only when a prompt is really coming. Co-Authored-By: Claude Opus 5 (1M context) --- install.sh | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index afef803..1985e71 100755 --- a/install.sh +++ b/install.sh @@ -322,6 +322,34 @@ persist_brew_shellenv() { ok "Added Homebrew to PATH in $profile" } +# Homebrew's installer runs its sudo pre-flight check as `sudo -n` whenever +# NONINTERACTIVE is set, so that check can never prompt. On a machine that has +# just booted there is no cached sudo timestamp yet, so it fails and the +# installer aborts with "Need sudo access on macOS (e.g. the user ... needs to +# be an Administrator)!" — even when the user is an administrator. +# +# Prime the timestamp ourselves first, with a `sudo` that is allowed to ask. +# The installer's own privileged commands run without `-n`, so they re-prompt +# on their own if the timestamp expires later in the run. +prime_sudo() { + # Nothing to do when the timestamp is still within its grace period from an + # earlier run, or when sudo is passwordless here. `sudo -v` would be a + # harmless no-op in that case anyway, but checking first keeps us from + # announcing a password prompt that is never going to appear. + if sudo -n -v 2>/dev/null; then + return 0 + fi + + log "sudo will ask for your password" + # An `if` condition, not `sudo -v || die`, so that errexit does not fire + # before the diagnosis below is printed. + if sudo -v; then + return 0 + fi + printf '\n' >&2 + die "could not obtain sudo access, which the Homebrew installer requires. Check that $(whoami) is an administrator: System Settings > Users & Groups." +} + ensure_homebrew() { local brew_bin if have brew; then @@ -337,10 +365,10 @@ ensure_homebrew() { fi log "Installing Homebrew (this also installs the Xcode Command Line Tools)" - log "sudo will ask for your password" if [ ! -t 0 ] && [ ! -e /dev/tty ]; then - warn "no terminal available; the Homebrew installer cannot prompt for your password" + warn "no terminal available; sudo cannot prompt for your password" fi + prime_sudo NONINTERACTIVE=1 /bin/bash -c \ "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \ || die "Homebrew installation failed"