History
- 2024-3-20: Created the technical note while evaluating macOS 14.4 upgrade and Homebrew update.
Homebrew installs softwares in /usr/local
/usr/local
is the default file path that Homebrew
install softwares in for Mac computers with an Intel CPU.
The Homebrew documentation says:
The script installs Homebrew to its default, supported, best prefix (
/opt/homebrew
for Apple Silicon,/usr/local
for macOS Intel and/home/linuxbrew/.linuxbrew
for Linux) so that you don’t need sudo after Homebrew’s initial installation when you brew install. This prefix is required for most bottles (binary packages) to be used. It is a careful script; it can be run even if you have stuff installed in the preferred prefix already. It tells you exactly what it will do before it does it too. You have to confirm everything it will do before it starts.The macOS
.pkg
installer also installs Homebrew to its default prefix (/opt/homebrew
for Apple Silicon and/usr/local
for macOS Intel) for the same reasons as above. It’s available on Homebrew/brew’s latest GitHub release. To specify an alternate install user, like in situations where the package is installed at the login window before a user has logged in, write a property list file to /var/tmp/.homebrew_pkg_user.plist with the value HOMEBREW_PKG_USER. For example, defaults write /var/tmp/.homebrew_pkg_user HOMEBREW_PKG_USER penny. The file and user must exist prior to install.
(c.f. https://web.archive.org/web/20240320193541/https://docs.brew.sh/Installation)
brew doctor
compalining on owner and permission of
files and sub-directories in /usr/local/
brew doctor
sometimes advices chaning owner of
files and directories in /usr/local
to yourself.
For experimenting, temprarily change the owner of
/usr/local/include
sub-directory to
root
:
$ sudo chown root /usr/local/include
Password:
$ ls -ld /usr/local/include
Then observe brew doctor
suggests changing it: ```
$ brew doctor Please note that these warnings are just used to help
the Homebrew maintainers with debugging if you file an issue. If
everything you use Homebrew for is working fine: please don't worry
or file an issue; just ignore this. Thanks!
Warning: The following directories are not writable by your user: /usr/local/include
You should change the ownership of these directories to your user. sudo chown -R xxx /usr/local/include
And make sure that your user has write permission. chmod u+w
/usr/local/include `` (where
xxx` is the username of
the current user.)
macOS's System Integrity Protection feature protects
/usr/local
directory but not files and directories
inside it
Before macOS's System
Integrity Protection (SIP) feature was introduced in OS X El
Capitan in 2015 , the root
user, and Homebrew and any
software that obtained root-level permission when the administrator
entered the username and password to install the software, can
modify or overwrite any system file or app. SIP protects
/usr
and /usr/local/
(but NOT the files
and sub-directories inside /usr/local/
) among others
and prevent its owner and permission to be modified:
$ ls -ld /usr/local
drwxr-xr-x 18 root wheel 576 Mar 15 20:02 /usr/local
$ sudo chown $(whoami):wheel /usr/local
Password:
chown: /usr/local: Operation not permitted
However, all the files and directories inside
/usr/local
are allowed can be modified by the
root
user and Homebrew
.
So, the sudo user and softwares with sudo-level permission are
allowed to change the ownership and permission of files and
sub-directories inside /usr/local/
, i.e.
/usr/local/*
.
c.f. Apple. “About System Integrity Protection on your Mac”. 2023. https://web.archive.org/web/20240320060257/https://support.apple.com/en-us/102149.
But Homeberew does NOT need to change the owner of
/usr/local
directory itself
Since 2016, Homebrew creates necessary directories inside
/usr/local
and check their ownership and permission
instead of requiring it on /usr/local
directory itself
(c.f.
https://apple.stackexchange.com/questions/253404/how-does-homebrew-no-longer-need-ownership-of-usr-local).
Finding out the unique user and group values on your computer
Using [OpenBSD's version of stat
][stat], one can
find the unique ownership values of files and sub-directories in
/usr/local/
, but be aware this took as long as 2 and a
half hours on my computer:
$ gfind "$(brew --prefix)" -mindepth 1 -exec stat -f '%Su:%Sg' '{}' \; | sort -u
xxx:_lpoperator
xxx:staff
xxx:wheel
root:staff
root:wheel
You can also exclude "$(id -un):wheel"
:
$ gfind "$(brew --prefix)" -mindepth 1 -not -user $(id -un) -or -not -group wheel -exec stat -f '%Su:%Sg' '{}' \; | sort -u
$ xxx:_lpoperator
xxx:staff
More commands for reference:
#+ Finding sub-directories and files in $(brew --prefix) that do not have
#+ ownership as $(id -un):wheel
#+
#$FIND_BIN "$(brew --prefix)" -mindepth 1 -not -user $(id -un) -or -not -group wheel -exec sudo chown $(id -un):wheel '{}' \;
#$FIND_BIN /opt/homebrew-cask -not -user $(id -un) -or -not -group wheel -exec sudo chown $(id -un):wheel '{}' \;
#$FIND_BIN "$HOME/Library/Caches/Homebrew" -not -user $(id -un) -exec sudo chown $(id -un) '{}' \;
Fixing the owner, group, and permission of the content in
/usr/local
As of 2024-3, it is still a open question for myself what user
and group should be set to the sub-directories and files in
/usr/local
and how best to do so.
One possibility I'm evaluating is to set all sub-directories and
files in /usr/local
to root:wheel
first
then run brew doctor
and set the problematic ones to
xxx:wheel
or whatever it suggests.
It looks roughly as:
echo "[INFO] Start checking and fixing file ownership and permission:"
sudo chown -R root:wheel $(brew --prefix)/*
sudo chown -R $(id -un):wheel \
/usr/local/Caskroom \
/usr/local/Cellar \
/usr/local/Frameworks \
/usr/local/Homebrew \
/usr/local/bin \
/usr/local/etc \
/usr/local/include \
/usr/local/lib \
/usr/local/opt \
/usr/local/sbin \
/usr/local/share \
/usr/local/var/homebrew
sudo chown -R $(id -un):wheel /opt/homebrew-cask
sudo chown -R $(id -un) "$HOME/Library/Caches/Homebrew"
#+
#+ Fix read and write permission of files and folders recursively for the
#+ user so Homebrew can create and modify files there for installing
#+ softwares without using sudo.
sudo chmod -R u+rw $(brew --prefix)/* /opt/homebrew-cask "$HOME/Library/Caches/Homebrew"
#+ Fix execute permission of folders recursively, so content inside
#+ are accessible by the user and the group
#+ (c.f. <https://superuser.com/questions/168578/why-must-a-folder-be-executable>.)
#+
sudo $FIND_BIN $(brew --prefix) /opt/homebrew-cask "$HOME/Library/Caches/Homebrew" -type d -exec chmod ug+x '{}' \;
## Fix write permission of zsh folders. c.f. <https://archive.ph/dL8U1>
type zsh >/dev/null 2>&1 && type compaudit >/dev/null 2>&1 && compaudit | xargs chmod g-w
TeXLive manager tlmgr
also has the same permission
issue with /usr/local
Observe that TeXLive manager tlmgr
also have
permission issue with /usr/local
:
$ tlmgr install standalone
You don't have permission to change the installation in any way,
specifically, the directory /usr/local/texlive/2024/tlpkg/ is not writable.
Please run this program as administrator, or contact your local admin.
tlmgr: An error has occurred. See above messages. Exiting.
Check its current owner, group, and permission: $ ls -ld
/usr/local/texlive/2024/tlpkg/ drwxr-xr-x 13 root wheel 416 Mar 12
11:13 /usr/local/texlive/2024/tlpkg/
root:wheel
is the default owner when
mactex
is installed via Homebrew: $ brew install
--cask mactex
See https://github.com/orgs/Homebrew/discussions/4226#discussioncomment-5008376.