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
-
For maven you just need to edit the shell start files in your home directory. The more complex ways are for running guide appsmmmmmm– mmmmmm2017年03月06日 11:22:41 +00:00Commented Mar 6, 2017 at 11:22
5 Answers 5
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.
-
2Excellent and pretty detailed answer!Saïd– Saïd2021年10月14日 16:04:32 +00:00Commented Oct 14, 2021 at 16:04
-
1What beautiful answer! You saved me hours of reading, and promoted hours of further reading (now that I know there is a complicated "load order" to zsh).Motti Shneor– Motti Shneor2023年02月04日 07:53:14 +00:00Commented Feb 4, 2023 at 7:53
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
-
Typically, you do not want to update the path by adding a new directory to the end of it as any executables in this directory will have the least precedence, and executables in directories earlier in the path will be used.Schlueter– Schlueter2021年10月19日 17:41:03 +00:00Commented Oct 19, 2021 at 17:41
-
1Changing it this way is just for the current session. This won't help for new terminal tabs or windows unless you want to redo this
exportevery time.chicks– chicks2022年01月14日 01:03:08 +00:00Commented Jan 14, 2022 at 1:03 -
In zsh, I use for this purpose the array
pathinstead ofPATH, as it is more convenient to handle. I also do atypeset -aU pathto ensure that duplicate entries get automatically removed.user1934428– user19344282023年03月17日 07:54:13 +00:00Commented Mar 17, 2023 at 7:54
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.
-
Modifying the system path (which modifying the path in most places outside of your home directory does) can have unexpected consequences. Typically, you should just modify your user's path as this will not affect system utilities which may rely on the default system path.Schlueter– Schlueter2021年10月19日 17:43:21 +00:00Commented Oct 19, 2021 at 17:43
-
@bschlueter The tool that adds these paths from /etc/paths puts these paths after any others so the only issue would be if you expected a command to be not found on the PATHmmmmmm– mmmmmm2022年02月18日 00:00:24 +00:00Commented Feb 18, 2022 at 0:00
-
I didn't say I expected there to be an issue, just that these are system files, and there is a place, your home directory, where these changes are meant to be made for your shell. When you make changes to system configuration rather than your shell configuration, it is possible to affect how other programs run, which is frequently not desirable or what the creators of those programs expected.Schlueter– Schlueter2022年02月18日 20:45:14 +00:00Commented Feb 18, 2022 at 20:45
This example adds ~/Library/Python/3.9/bin to your path for both the current and future terminals:
echo "export PATH=\$PATH:~/Library/Python/3.9/bin" >> ~/.zshrc
source ~/.zshrc
If your using zsh
- edit zshrc
- source ~/.zshrc
- exit that terminal by command + w
it will save your changes permanently.