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.


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


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


is similar to .zlogin - they set the environment for login shells, except that it is read before .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


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]


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


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.


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.


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]