Installing Home Brew for Standard Users

CodyC
New Contributor II

Has anyone been able to successfully accomplish this? I have tried several scripts ive found on these discussions as well as AutoBrew.

The end result is the same, and its always a lack of permissions.Error: /usr/local is not writable. You should change the
ownership and permissions of /usr/local back to your
user account: sudo chown -R $(whoami) /usr/local

So, is it possible to install this for a Standard user and allow them to update and install via brew, or does this require Admin?

-Cody
1 ACCEPTED SOLUTION

Jimbo
New Contributor III

I believe there's an error in that script posted above. If you copy/paste that script into Jamf and look at line 90, it reads:

chown -R "${consoleuser}":_developer /usr/local/*

It should instead read:

chown -R "${consoleuser}:_developer" /usr/local/*

The quotation mark is off.

View solution in original post

10 REPLIES 10

bwoods
Valued Contributor
#!/bin/bash

# Script to install Homebrew on a Mac.
# Author: richard at richard - purves dot com
# Version: 1.0 - 21st May 2017

# Heavily hacked by Tony Williams (honestpuck@gmail.com)
# Latest version at https://github.com/Honestpuck/homebrew.sh
# v2.0 - 19th Sept 2019
# v2.0.1 Fixed global cache error
# v2.0.2 Fixed brew location error
# v2.0.3 Added more directories to handle

# v3.0 Catalina version 2020-02-17
# v3.1 | 2020-03-24 | Fix permissions for /private/tmp
# v3.2 2020-07-18 Added Caskroom to directories created and added check for binary
# update if it exists then exit

# Set up variables and functions here
consoleuser="$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')"

if [[ -e /usr/local/bin/brew ]]; then
    su -l "$consoleuser" -c "/usr/local/bin/brew update"
    exit 0
fi

# are we in the right group
check_grp=$(groups ${consoleuser} | grep -c '_developer')
if [[ $check_grp != 1 ]]; then
    /usr/sbin/dseditgroup -o edit -a "${consoleuser}" -t user _developer
fi

# Logging stuff starts here
LOGFOLDER="/private/var/log/"
LOG="${LOGFOLDER}Homebrew.log"

if [ ! -d "$LOGFOLDER" ]; then
    mkdir $LOGFOLDER
fi

function logme()
{
# Check to see if function has been called correctly
    if [ -z "$1" ] ; then
        echo "$(date) - logme function call error: no text passed to function! Please recheck code!"
        echo "$(date) - logme function call error: no text passed to function! Please recheck code!" >> $LOG
        exit 1
    fi

# Log the passed details
    echo -e "$(date) - $1" >> $LOG
    echo -e "$(date) - $1"
}

# Check and start logging
logme "Homebrew Installation"

# Have the xcode command line tools been installed?
logme "Checking for Xcode Command Line Tools installation"
check=$( pkgutil --pkgs | grep -c "CLTools_Executables" )

if [[ "$check" != 1 ]]; then
    logme "Installing Xcode Command Tools"
    # This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
    touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
    clt=$(softwareupdate -l | grep -B 1 -E "Command Line (Developer|Tools)" | awk -F"*" '/^ +\*/ {print $2}' | sed 's/^ *//' | tail -n1)
    # the above don't work in Catalina so ...
    if [[ -z $clt ]]; then
        clt=$(softwareupdate -l | grep  "Label: Command" | tail -1 | sed 's#* Label: (.*)#1#')
    fi
    softwareupdate -i "$clt"
    rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
    /usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
fi

# Is homebrew already installed?
if [[ ! -e /usr/local/bin/brew ]]; then
    # Install Homebrew. This doesn't like being run as root so we must do this manually.
    logme "Installing Homebrew"

    mkdir -p /usr/local/Homebrew
    # Curl down the latest tarball and install to /usr/local
    curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C /usr/local/Homebrew

    # Manually make all the appropriate directories and set permissions
    mkdir -p /usr/local/Cellar /usr/local/Homebrew mkdir /usr/local/Caskroom /usr/local/Frameworks /usr/local/bin
    mkdir -p /usr/local/include /usr/local/lib /usr/local/opt /usr/local/etc /usr/local/sbin
    mkdir -p /usr/local/share/zsh/site-functions /usr/local/var
    mkdir -p /usr/local/share/doc /usr/local/man/man1 /usr/local/share/man/man1
    chown -R "${consoleuser}":_developer /usr/local/*
    chmod -R g+rwx /usr/local/*
    chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions

    # Create a system wide cache folder  
    mkdir -p /Library/Caches/Homebrew
    chmod g+rwx /Library/Caches/Homebrew
    chown "${consoleuser}:_developer" /Library/Caches/Homebrew

    # put brew where we can find it
    ln -s /usr/local/Homebrew/bin/brew /usr/local/bin/brew

    # Install the MD5 checker or the recipes will fail
    su -l "$consoleuser" -c "/usr/local/bin/brew install md5sha1sum"
    echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' | 
    tee -a /Users/${consoleuser}/.bash_profile /Users/${consoleuser}/.zshrc
    chown ${consoleuser} /Users/${consoleuser}/.bash_profile /Users/${consoleuser}/.zshrc

    # clean some directory stuff for Catalina
    chown -R root:wheel /private/tmp
    chmod 777 /private/tmp
    chmod +t /private/tmp
fi

# Make sure everything is up to date
logme "Updating Homebrew"
su -l "$consoleuser" -c "/usr/local/bin/brew update" 2>&1 | tee -a ${LOG}

# logme user that all is completed
logme "Installation complete"

exit 0

CodyC
New Contributor II

I've tried that exact script, but still have the same results. Unable to install anything (brew install **) or update (brew update).

For my own sanity, I have copied and pasted the code above into a script in Jamf and deployed via Policy. Something else im missing here?

-Cody

Jimbo
New Contributor III

I believe there's an error in that script posted above. If you copy/paste that script into Jamf and look at line 90, it reads:

chown -R "${consoleuser}":_developer /usr/local/*

It should instead read:

chown -R "${consoleuser}:_developer" /usr/local/*

The quotation mark is off.

bwoods
Valued Contributor

Hey @CodyC , you need to install Xcode command line tools before running this script. It works just fine when running in self service for me. Just figure out a workflow to get Xcode CLI installed before running this. Hope this helps.

CodyC
New Contributor II

Other than taking 7 minutes to install, it looks great. Thanks for the quotation mark find, my standard user can now use this without issue.

-Cody

Jason33
Contributor III

The only problem that I'm running into with standard users installing apps via Homebrew is a prompt for admin name/password to move an application to the /Applications folder.

Mark_Lamont
New Contributor II

@CodyC and everyone else. this script is working ok for me. I tweaked it a bit and those changes are now in the script. It works on both Intel and ARM. I used it on Intel 10.15.7 and ARM Big Sur

quip_MDavison
New Contributor III

Hi all.  I tried the updated script @Mark_Lamont posted and our users are still getting the error asking to be assigned permissions to the /usr/local folder.  Happens on Catalina 10.15.7 and Big Sur.  Even trying to run the commands manually it gives a ton of Operation Not Permitted errors.  Doesn't seem to matter if the user is an admin or not.

➜  data  git:(terraform) source venv/bin/activate
(venv) ➜ data git:(terraform) brew install hashicorp/tap/terraform
Error: The following directories are not writable by your user:
/usr/local/binYou should change the ownership of these directories to your user.
sudo chown -R $(whoami) /usr/local/binAnd make sure that your user has write permission.
chmod u+w /usr/local/bin
(venv) ➜ data git:(terraform)

 

mrnicker9
New Contributor

@bwoods, this script really helped us out for Intel MacBooks. Is there another variant for M1 Silicon MacBooks that you are aware of?

NateES
New Contributor III

I'm currently noticing an issue with ARM MacBooks where - if the above script is run on a machine with a pending update, somehow it will change ownership via the /private/tmp/ folder and propagate through the entire system - requiring a full machine rebuild to fix.