How do I add a directory to PATH when using `zsh` in Sierra

In macOS Sierra 10.12.x, what is the modern way to add a directory to the PATH environment variable that can work across shells or specifically work with zsh shell (I switched from the default bash to zsh).

I have seen some Questions and Answers such as this one that are bash-specific. And I have seen some such as this one about launchd but it seems I've read launchd is not the right right in later versions of macOS (not sure). I could find no specific references for Sierra, so I am posting now.

I am trying to install Maven with instructions saying:

Add the bin directory of the created directory apache-maven-3.3.9 to the PATH environment variable


Solution 1:

export

To change the path within your shell session, not system-wide, you can use the bash-style export command with zsh, as documented here.

The name of the PATH variable is case-sensitive and must be all-uppercase.

export PATH=$PATH:/folder/you/want

To verify your change, run:

echo $PATH

You will see results like this.

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/folder/you/want

Solution 2:

This answer (to a different question) suggests modifying /private/etc/paths or adding a file to the directory /private/etc/paths/d. I just tried sudo nano /private/etc/paths, added /foo at the end of the file, and opened a new tab in Terminal, and echo $PATH showed /foo as expected, in both bash and zsh shells.

Assuming you've installed Maven to /opt/apache-maven-3.3.3 you could add /opt/apache-maven-3.3.3/bin to /private/etc/paths. However, and I've not tried this (it's been several years since I last did any Java development), I'd be inclined to instead add a file Maven (containing /opt/apache-maven-3.3.3/bin) to /private/etc/paths.d - that'll encapsulate the Maven-specific path change, making it easier to clean up if you ever delete (or upgrade) Maven.

Solution 3:

In zsh, including on macOS, you should add entries to your path in your .zshrc. By default this file is read from the directory located in $ZDOTDIR which defaults to $HOME if not set.

To add an entry there, you may follow instructions for bash and add a line such as:

export PATH=/opt/apache-maven-3.8.2/bin:$PATH

or because zsh also offers an interface to the path in the $path environment variable, which is an array, you may also use:

export path=(/opt/apache-maven-3.8.2/bin $path)

Either of these will add /opt/apache-maven-3.8.2/bin to your path before the previous contents of the path.

The order is important particularly for programs such as zsh which may be present at /bin/zsh and at /usr/local/bin/zsh, as would be the case if it is installed using homebrew (/bin/zsh being the default installation). If you install it separately, you probably want to use it and so should make sure that /usr/local/bin precedes /bin on your path, so to add it you should use:

path=(/usr/local/bin $path)

in that order. And don't forget to export it after updating it with export path or precede path= with export.

If you are heavily customizing your zsh installation, you may be tempted to set the path in $ZDOTDIR/.zshenv. This should be avoided. Prior to loading that file, /etc/zprofile is read, which in a default macOS installation executes:

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

Which will screw the ordering of any customizations to your path. See the zsh man page with man zsh for the details of the load order or man path_helper for an explanation of that utility.