Immae's blog

egrep -ri TODO /etc

Shell invocation

Languages: French

Bash and Zsh shells have very different ways to start, and this can be an issue when we switch from one to the other and back.

First, we distinguish two states for the shell:

Shells make different actions depending on those two states.

Login shell

To indicate to a shell that it is a login shell, the calling process will simply add a - in front of his name (thus the shell will be called -bash or -zsh). Some shells (like bash) allow command line argument to fake login shells.

In a script, we can tell wether we are a login shell or not in a simple way:

Bash
shopt -q login_shell
Zsh
[[ -o login ]]

Interactive shell

A shell is interactive if it is invoked without argument (or at least none that imply a command).

In a script, we can tell wether we are an interactive shell: suivante :

[[ $- == *i* ]]
(It is possible to have an interactive shell with a script, for instance if a file is sourced).

Zsh behavior when invoked

  1. In all cases, /etc/zshenv and ~/.zshenv are sourced (in this order).
  2. If it is a login shell, /etc/zprofile and ~/.zprofile are sourced (in this order)

    Note

    /etc/zprofile is chosen at compile-time and can vary depending on the system (On Archlinux it is /etc/zsh/zprofile).

  3. If we have an interactive shell, /etc/zshrc and ~/.zshrc are sourced (in this order).
  4. Finaly, if it is a login shell (again!), /etc/zlogin et ~/.zlogin are sourced (in this order).

Bash behavior when invoked

  1. If it is a login and interactive shell, /etc/profile is sourced, and then the first existing one in ~/.bash_profile, ~/.bash_login, ~/.profile.
  2. If it is an interactive non-login shell, ~/.bashrc is sourced.
  3. Finaly, if the shell is non-interactive, $BASH_ENV is sourced (if available).

Bash behavior when invoked as sh

In many distributions, sh is simply a soft link to bash. In that case, bash will behave in a different way when invoked:

  1. If it is an interactive login shell, /etc/profile and ~/.profile are sourced.
  2. If $ENV is a file, it is also sourced.