Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZSH PATH variable entries are backwards on OS X Catalina

Tags:

path

macos

zsh

So I just installed macOS Catalina and MacPorts. This caused me to have to modify the PATH and MANPATH enviroment variables in my .zshenv file as follows:

# configure an environment variable for Racket
export RACKET=/Applications/Racket

# configure an appropriate PATH variable for use with MacPorts
export PATH="/opt/local/bin:/opt/local/sbin:$RACKET/bin:$PATH"

# configure an appropriate MANPATH variable for use with MacPorts
export MANPATH="/opt/local/share/man:$RACKET/man:$MANPATH"

However, running the following command echo $PATH gives me the reverse of what I'd expect:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin:/opt/local/sbin:/Applications/Racket/bin

Any ideas on what I should do to remedy this? The fact that the entires for /opt/local/* are towards the end are breaking some build scripts for quite a utilities that I use.

like image 229
Gregory Gelfond Avatar asked Dec 02 '19 02:12

Gregory Gelfond


2 Answers

Add code below in ~/.zshrc or ~/.zprofile:

# Prepend the $PATH
[[ -f $HOME/.zshenv ]] && source $HOME/.zshenv 
# remove duplicate $PATH
typeset -U PATH

Explanation:

According to the zsh loading order, for any login-shell in zsh, it would call etc/zprofile after ~/.zshenv but before ~/.zshrc, which contains usr/libexec/path_helper:

 # file: etc/zprofile
 # system-wide environment settings for zsh(1)
if [ -x /usr/libexec/path_helper ]; then
   eval `/usr/libexec/path_helper -s`
fi

The code above moves the /usr/bin:/bin:/usr/sbin:/sbin ahead of your self-added $PATH such as /opt/local/bin:/opt/local/sbin...

We source the .zshenv again after the /etc/zprofile to add self-added path to the front again , type -U PATH keep the path remain at the first place appeared and remove duplicate one.

like image 94
yinz Liu Avatar answered Nov 26 '22 08:11

yinz Liu


I suspect the issue is that .zshenv executes before any other startup files, which are also modifying PATH. (This isn't a full explanation, as /etc/zprofile should be overwriting PATH, not prepending to it. But it's close.)

Instead of setting PATH in .zshenv (which is sourced for all shells, interactive or not), do it in ~/.zprofile instead.

See the section on startup/shutdown files in man zsh for a full explanation of which files are sourced and when.

like image 40
chepner Avatar answered Nov 26 '22 10:11

chepner