| `/etc/zshenv` | | | system provided minimal environment | Always runs! should be minimal set ZDOTDIR, minimal environment. system paths
| | | `${ZDOTDIR:-$HOME}/.zshenv` | user environment overrides non-interactive, non-login shells (when invoked via shebang in a script or via `zsh -c [script]` or when invoked by `make` | personal environment overrides, such as `MANPATH`, `TERM`, `fpath`*non interactive scripts should have their environment completly set up here* )
| | `/etc/zshprofile` | | system profile for login shells (`zsh -ls zsh - or via _ssh forced command_`) | minimal system paths for remote interaction, site `fpath`, site `$LOCALE`, lang.
| | | `${ZDOTDIR:-$HOME}/.zshprofile` | personal preferences for interactive login shells | your preferred `$LOCALE`, `$LANG`, `readlne` config, `cdpath`, session managers, additional `fpath` ) login shells (but non necessarily **ineractive** as when invoked via _ssh remote cmd_ ) will read config up to this point
| | `/etc/zshrc` | | system provided startup script, for interactive shells, (local shells that live in an `XTerm`, `URxvt`, `gnome-terminal`) or subshells (like running `xterm` from the command prompt of a _login xterm_, | site login accounting, security monitors, site command logging policy
| | | `${ZDOTDIR:-$HOME}/.zshrc` | user customization of their *interactive* environment for terminals | sourcing custom completions (`gcloud.comp.inc`), custom user frameworks (zprezto is invoked here), additional path required by custom software installed in `/opt/*`
| | `/etc/zshlogin` | | additional customization for interactive **login** shells, such as those accessed via ssh | tmux attach to existing session
| | | `${ZDOTDIR:-$HOME}/.zshlogin` | user script for *login shell startup* (this shell is a session leader, and allocates a `ptty` | aliases, keybindings, personal startup programs, time tracking apps, session managers, quote of the day, fortunes
| .. | ... your shell session happens here ... |
| | | `${ZDOTDIR:-$HOME}/.zshlogout` | personal cleanup tasks | setting personal `crontabs` or `at` tasks, logging checout to your time tracking software, fortune to say goodbye.
| `/etc/zshlogout` | | | site cleanup tasks | site command logging policy stop, login accounting records, security context spindown, etcThe configuration files are read in the following order:
Discussion
----------
There are several places to add personal configuration and preferences in
the files already provided for startup, it’s just a matter of placing them
in the appropriate place. Most of them should probably go in
`${ZDOTDIR:-$HOME}/.zshrc`**before** invoking zprezto init, to choose
the modules that should get loaded, and using the appropriate `zstyle`
calls form preferences (`zstyle` is a kind of _registry_ for shell configuration
native to `zsh`)
Any tweaks to prezto’s behavior should go **after** invoking zprezto init
in `zshrc` or, in `${ZDOTDIR:-$HOME}/.zlogin` . Note however that the
`zlogin` (sysem or user) files will be sourced **only for login shells**.
That means, when logging in to a remote system via ssh for example or
when calling say, `XTerm` or your favorite emulator by specifying you
want a **login** shell (by calling `zsh -ls` instead of plain `zsh`).
Otherwise, the `zlogin` files are ignored.
Also, note that another difference between interactive login shells and
plain interactive shells, is that, besides sourcing `zlogin` files,
interactive login shells also allocate a pseudo-tty (you can see them when
invoking `w`. Login shells have a pty assigned, while interactive non-login
shells don't.)
Why is this designed this way? because login shells are assumed to be
the main point of interaction with a user while non login shells would
be spawned as _sub-shells_ of a *login shell* , when executing scripts
that call `zsh` as a command interpreter, for example, when the *shebang* is
`#!/usr/bin/env zsh` or equivalent.
When launching a new terminal within an *X11* session, it is safe to
assume that you are *already logged in* so any terminal emulator will
launch an *interactive-non-login* shell. Which is, _per specification_
the correct behavior, but not the behavior most users *expect*.
There is a reason for this _specified_ behaviour: `zlogin` files should
be used for *interaction oriented settings* such as custom completion,
keybindings, `tmux` session setup, and most `alias`es.
The advantage of grouping all interaction oriented settings in
`.zlogin` is that non-interactive shells (executing scripts via
`zsh -c [script]`, the *shebang*, subshells or `make` invoked shells,
for example) will not be burdened by additional config settings making
them faster and more responsive, as _keybindings_ and _aliases_ are not
even loaded at startup, after all, an _executable non-interactive script_,
should never call on keybindings or aliases (assuming they were properly
written to be portable)
Finally, it is a common source of frustration amongst graphical environment
users, to spend some time adding their customizations to `.zlogin` only
to see them ignored when launching a new `XTerm` or `tmux` pane.
This can be solved by calling (or aliasing) your terminal emulator with
the required option to invoke a *login* shell, for `XTerm`, for example
you would call `xterm -e zsh -ls` on tmux you may add one of the following
lines to your `.tmux.conf`:
```config
#tmux.conf:
set -g default-command 'exec /usr/bin/zsh -ls' #this will make zsh a login shell AND a session leader
set -g default-shell '/usr/bin/zsh -ls'
```
Here is an examplefor *i3wm* on ubuntu
```bash
#i3wm.conf:
...
set $XTERM_CMD='xterm -e zsh -ls`
bind $mod+x $XTERM_CMD
...
```
if you want to replace your non-login shell on your emulator with a brand-new
shiny *login* shell you can issue `exec zsh -ls` at your command prompt.
Doing this, however **will not write that terminal’s history to file** unless
`INC_APPEND_HISTORY` was set when you strted the shell
`INC_APPEND_HISTORY` makes `zsh` append history entries as soon as the
command is finished. *zprezto* helpfuly sets `INC_APPEND_HISTORY`,
`INC_APPEND_HISTORY_TIME`, and `SHARE_HISTORY` which makes your history
available immediately from different terminals on command completion,
and records execution time on the history file. Pretty neat, huh?)
You could tack-on all interactive customizations on `zshrc` but you will
end up with bloated shells on non-interactive environments. Perhaps desktop
workstation users will not notice any difference, but in resource-constrained
environments it may be significant in terms of execution time and energy
consumption (v.gr when running a Raspberry PI on batteries or on a cell
phone environment such as `termux`)
You may be thinking... why is `zpreztorc` not invoked on `.zlogin` instead
of `.zshrc`? I believe it was a wise design decision, in order to
eliminate complexity by having the whole of *prezto* configured and
launched from a single point, as some of the modules need to be sourced
early in the startup process, `editor` and `gnu-utls` come to mind.
If invoked later on the startup, such as would be the case in `.zlogin`
would makee it easier to conflict with stuff users may add on `zshrc`.
Also, it avoids **not being loaded** and causing user frustration if
the user launches *non-login shells* from graphical environments, as
discussed above.
## Conclusion
For customization of your environment, use your `.zshrc` after zprezto
has been invoked, or before to remove or activate packages via `zstyle`
calls
or
use `.zshlogin` to override or tweak zprezto behavior. there is also
`.zpreztorc` but you may want to leave that one alone.
In any case, this question is often brought up by users that use the
distributed *runcoms***as is** which is a terrible idea, since doing
`git pull` to update your distribution will clobber your customizations.
it’s a better idea to *copy* the distributed *runcoms* to your `$ZDOTDIR` a
nd merge any changes an update may bring, if any (they are usually