Different between .zprofile .zshrc .zshenv .zlogin .zlogout

These files (.zprofile .zshrc .zshenv .zlogin .zlogout) are all Zsh configuration files, set the environment variables for Zsh.

Zsh is a UNIX command interpreter (shell).

File position

These files under the user home directory, for example ~/.zprofile.

Usage

Put login-time configuration (usually mostly environment variables) in ~/.zprofile, and interactive configuration (prompt, completion, key bindings, aliases, …) in ~/.zshrc. You’ll rarely need the other startup files. 1

File function and difference

.zlogin

is read in login shells. It should contain commands that should be executed only in login shells.

.zprofile

is similar to .zlogin - they set the environment for login shells, except that it is read before .zshrc.

.zshrc

is read in interactive shells. This gets loaded after .zprofile. It’s typically a place where you “set it and forget it” type of parameters like $PATH, $PROMPT, aliases, functions, options and key bindings you would like to have in both login and interactive shells. 2

Note

The *profile files and the *login files are read under the same conditions: if and only if the shell is a login shell (and not invoked with an option such as no_rcs). The manual lists them separately because they’re invoked in a different order relative to the *rc files.

Often it doesn’t matter whether you use *profile or *login. But *profile files have the advantage that they’re read before *rc, so if you have *rc content that depends on settings from *profile (for example, if your .zshrc calls a program which is in a directory that .zprofile adds to $PATH), you need to use *profile and not *login. [^3]

.zshenv

is always read on all invocations of the shell, unless the -f option is set. It should contain commands to set the command search path, plus other important environment variables. But should not contain commands that produce output or assume the shell is attached to a tty. 3

This is geared more toward advanced users where having your $PATH, $PAGER, or $EDITOR variables may be important for things like scripts that get called by launchd. Those run under a non-interactive shell so anything in .zprofile or .zshrc won’t get loaded. (Personally, I don’t use this one because I set the PATH variable in my script itself to ensure portability.) 2

zlogout

is sourced when login shells exit. It is very good for cleaning things up when you leave (like clear or resetting the Terminal window title) 2

Order of operations

Keep in mind that it reads first from the system-wide file (i.e. /etc/zshenv) then from the file in your home directory (~/.zshenv) as it goes through the following order. 2

.zshenv -> .zprofile -> .zshrc -> .zlogin -> .zlogout

  • .zshenv, is sourced in all shells(both login and interactive, unless the -f option is set).
  • .zprofile, is sourced in login shells.
  • .zshrc, is sourced in interactive shells.
  • .zlogin, is sourced in login shells.
  • .zlogout, is sourced when login shells exit.

Shells

Interactive shells

are those whose input and output are connected to a terminal.

Login shells

(whether local or remote) that allows a user to authenticate to the system and start a session. These shells are typically interactive shells.

Note

On macOS, Terminal initially opens shell is a login shell also an interactive shell, even though you don’t authenticate (enter login credentials). However, any subsequent shells that are opened are only interactive.

SSH sessions are login and interactive so they’ll behave just like your initial Terminal session and read both .zprofile and .zshrc [^1]