Where to place $PATH variable assertions in zsh?
I love zsh
, but I am not sure where to place my $PATH
and other variable assertions? I find that they are scattered between the files .zshrc
.zprofile
.bashrc
.bash_profile
, and sometimes doubled.
I realize that having anything inside the bash
files doesn't make much sense seeing as I'm using zsh
, but where exactly should I be placing my rvm
, python
, node
etc additions to my $PATH
?
Is there a specific file I should be using (i.e. .zshenv
which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
Solution 1:
tl;dr version: use ~/.zshrc
And read the man page to understand the differences between:
~/.zshrc
,~/.zshenv
and~/.zprofile
.
Regarding my comment
In my comment attached to the answer kev gave, I said:
This seems to be incorrect - /etc/profile isn't listed in any zsh documentation I can find.
This turns out to be partially incorrect: /etc/profile
may be sourced by zsh
. However, this only occurs if zsh
is "invoked as sh
or ksh
"; in these compatibility modes:
The usual zsh startup/shutdown scripts are not executed. Login shells source /etc/profile followed by $HOME/.profile. If the ENV environment variable is set on invocation, $ENV is sourced after the profile scripts. The value of ENV is subjected to parameter expansion, command substitution, and arithmetic expansion before being interpreted as a pathname. [man zshall, "Compatibility"].
The ArchWiki ZSH link says:
At login, Zsh sources the following files in this order:
/etc/profile
This file is sourced by all Bourne-compatible shells upon login
This implys that /etc/profile
is always read by zsh
at login - I haven't got any experience with the Arch Linux project; the wiki may be correct for that distribution, but it is not generally correct. The information is incorrect compared to the zsh manual pages, and doesn't seem to apply to zsh on OS X (paths in $PATH
set in /etc/profile
do not make it to my zsh sessions).
To address the question:
where exactly should I be placing my rvm, python, node etc additions to my $PATH?
Generally, I would export my $PATH
from ~/.zshrc
, but it's worth having a read of the zshall man page, specifically the "STARTUP/SHUTDOWN FILES" section - ~/.zshrc
is read for interactive shells, which may or may not suit your needs - if you want the $PATH
for every zsh
shell invoked by you (both interactive
and not, both login
and not, etc), then ~/.zshenv
is a better option.
Is there a specific file I should be using (i.e. .zshenv which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
There's a bunch of files read on startup (check the linked man
pages), and there's a reason for that - each file has it's particular place (settings for every user, settings for user-specific, settings for login shells, settings for every shell, etc).
Don't worry about ~/.zshenv
not existing - if you need it, make it, and it will be read.
.bashrc
and .bash_profile
are not read by zsh
, unless you explicitly source them from ~/.zshrc
or similar; the syntax between bash
and zsh
is not always compatible. Both .bashrc
and .bash_profile
are designed for bash
settings, not zsh
settings.
Solution 2:
Here is the docs from the zsh man pages under STARTUP/SHUTDOWN FILES section.
Commands are first read from /etc/zshenv this cannot be overridden.
Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the
former affects all startup files, while the second only affects global
startup files (those shown here with an path starting with a /). If
one of the options is unset at any point, any subsequent startup
file(s) of the corresponding type will not be read. It is also possi-
ble for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and
GLOBAL_RCS are set by default.
Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login
shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zpro-
file. Then, if the shell is interactive, commands are read from
/etc/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login
shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.
From this we can see the order files are read is:
/etc/zshenv # Read for every shell
~/.zshenv # Read for every shell except ones started with -f
/etc/zprofile # Global config for login shells, read before zshrc
~/.zprofile # User config for login shells
/etc/zshrc # Global config for interactive shells
~/.zshrc # User config for interactive shells
/etc/zlogin # Global config for login shells, read after zshrc
~/.zlogin # User config for login shells
~/.zlogout # User config for login shells, read upon logout
/etc/zlogout # Global config for login shells, read after user logout file
You can get more information here.
Solution 3:
I had similar problem (in bash terminal command was working correctly but zsh showed command not found error)
Solution:
just paste whatever you were earlier pasting in ~/.bashrc to:
~/.zshrc