The zsh shell is not only very powerful, but can also be confusing, expecially when it comes to choosing between .zprofile
, .zshenv
, .zshrc
files to configure the $PATH. As there are divergent opinions on Stack Overflow and web blogs, hopefully this gist can help to provide more clarification.
The most detailed background explanation I found is the gist by Linerre. While I really recommand to read it, the key aspect is that the configuration files are processed in the order .zshenv
, .zprofile
and .zshrc
, as on macOS a zsh shell is always treaded as a login shell. MacOS further changes the $PATH after the processing of .zshenv
with the path_helper
, which could lead to unexpected behaviour when following the the zsh documentation which suggests to configure the $PATH in .zshenv
.
Therfore, I am configuring zsh in the following way:
.zshenv
: should contain environment variables (but not $PATH)
# e.g. environment variable for Java
export JAVA_HOME="/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home"
.zshrc
: should contain $PATH modifications, options, alias, keybindings, customization
# e.g. adapt $PATH
export PATH="$JAVA_HOME/bin:$PATH"
# e.g. set alias
alias gp="git pull"
# e.g. customize zsh
autoload -Uz compinit && compinit
Note that .zprofile
could alternatively be used for $PATH modification.
There are powerful tools like ohmyzsh to customize the zsh shell. But, one approach to understand more about zsh, might be implementing own customizations instead. For example, only a few lines of code are enough to add tab auto completion and show the current branch in the directories of a git repository.
# example .zshrc
# add git tab completion
autoload -Uz compinit && compinit
# customize version control system with vcs_info
autoload -Uz vcs_info
# configure a hook, that refreshs the version control information
# every time before the promt is displayed
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
# configure prompt
setopt prompt_subst
PROMPT='%2~'\$vcs_info_msg_0_' %# '
# define style of info for all git projects
# %F{240} color gray, start
# %b current branch name
# %f color gray, stop
zstyle ':vcs_info:git:*' formats '%F{240}(%b)%f'
Documents/Dokumentation(main) %
Interesting links to go further from here might be