Default behavior dictates the following order for ZSH startup files:
/etc/zshenv
~/.zshenv
/etc/zprofile
(if login shell)~/.zprofile
(if login shell)/etc/zshrc
(if interactive)~/.zshrc
(if interactive)/etc/zlogin
(if login shell)~/.zlogin
(if login shell)
Notes:
zshenv
is the place to set environment variableszshrc
is the place for aliases, functions etc
Setting environment variables in zshenv
means that they'll be present for
non-interactive uses (think cron commands). This is what you want.
At least Debian/Gentoo/Arch ship an /etc/zprofile
which sets (not adds to,
sets) a value for $PATH
. Because this file is sourced after ~/.zshenv
, any
value you may have set there is overridden.
Possible solutions:
- Move the system
/etc/zprofile
to/etc/zshenv
- Set your path in
~/.zprofile
, not~/.zshenv
Neither are great.
Moving /etc/zprofile
to /etc/zshenv
means whatever commands are there are
now invoked for every shell (rather than once at login). This is wasteful,
there's no need to (re)set your locale in every shell every time.
Setting environment variables in zprofile
means they'll be set once (on login)
and inherited by all shells invoked directly or indirectly. This mostly works.
The variables won't be present for (e.g.) cron commands and any exports must be
duplicated in your crontab.
References:
- ZSH Startup/Shutdown Files: http://zsh.sourceforge.net/Doc/Release/Files.html
- Arch bug: https://bugs.archlinux.org/task/35966
- Gentoo bug: https://bugs.gentoo.org/show_bug.cgi?id=19924
macOS has a similar issue - in /etc/zprofile it reorders the existing PATH