In this post, I want to share what I find about the Zsh startup files and their loading order in macOS.
login and interactive shell#
There are a lot of posts discussing what a login and interactive shell is. These two aspects are independent.
In different mode, zsh will source different startup files when it is started.
In Zsh, to test if the shell is login shell, we can test login
option:
if [[ -o login ]]; then
echo 'yes'
else
echo 'no'
fi
You can also use echo $0
and check if the first character in output is -
.
You can exit login/non-login shell using exit
.
For the login shell, logout
also works (it does not work for non-login shell).
wezterm#
In wezterm, every time we open a new tab, it will by default start a login shell using the $SHELL
env variable.
The way it does this is via prefixing argv0 with -
when spawning the shell.
It is a standard way in Linux to check if the shell is a login shell.
You can use echo $0
and check if the first character is -
.
ref:
- https://wezfurlong.org/wezterm/config/launch.html#launching-programs
- wezterm commit, use -$SHELL to launch login shell, https://github.com/wez/wezterm/commit/bc0766396d76813961de85d7ef15979197f0bc97
Zsh startup file source order#
According to man zsh
(the section about STARTUP/SHUTDOWN FILES
), the loading order of startup file is:
/etc/zshenv
$ZDOTDIR/.zshenv
if login_shell:
/etc/zprofile
$ZDOTDIR/.zprofile
endif
if interactive_shell:
/etc/zshrc
$ZDOTDIR/.zshrc
endif
if login_shell:
/etc/zlogin
$ZDOTDIR/.zlogin
endif
When the shell exit or logout, then the following script:
/etc/zlogout
$ZDOTDIR/.zlogout
For the login file, you can add something that is best done once for the login. For example, showing some greetings.
For the log out file, you can add some snippet to save the logout time:
logfile="$HOME/logoutfile"
if [[ -f $logfile ]]
then
echo "logging out: $(date)" >> $logfile
else
echo "logging out: $(date)" > $logfile
fi
These config files do not have to exist in the system at all. When you know their loading order, you can then customize based on your preference.
On macOS, the file /etc/zprofile
is especially evil, it run a utility called path_helper
,
which changes the PATH
variable in a weird way.
You can also my other posts for the details.
ref:
- what goes where, zshenv, zprofile, zshrc, zlogin, https://apple.stackexchange.com/q/388622/285595
- this post has good digram on shell startup: https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html
- zsh user guide (section 2.2 all the startup file): https://zsh.sourceforge.io/Guide/zshguide02.html#l6