Everyone is welcome here (except, of course, those who have borrowed books from me for and have not returned them yet 😉)

Understanding Bash startup scripts

Posted on février 28, 2018 in computer-science

Most bash users know about the potential existence of the scripts .bashrc, .bash_profile, .profile, .bash_login in their HOME directory. The role of these scripts is to setup the environment, that is, define the PATH, PS1, (prompt), EDITOR,... variables, aliases and functions, and maybe perform other tasks.

These scripts get executed at startup, but not systematically. To understand when they are processed, it is important to know that shells come into four flavors, depending on whether they are interactive or non-interactive, and login or non-login.

A few examples:

  • when you are already logged in, that is, you have opened a session, if you open a new terminal, you get an interactive non-login shell.

  • when you connect to a remote computer with ssh remote, you get an interactive login shell.

  • when you execute a command on a remote computer with ssh remote command, the script or the command is executed in a login non-interactive shell.

  • When you execute a script starting with #! /bin/bash, it is launched in a non-interactive non-login shell.

Now for the rules:

  • Login shells first execute /etc/profile, then look for ~/.bash_profile, ~/.bash_login and ~/.profile, in that order, and reads and executes commands from the first one that exists.

  • Non-login interactive shells read and execute /etc/bash.bashrc, then ~/.bashrc (if they exist).

  • Non-interactive scripts typically do not execute and prior script; they just inherit the environment from which they are called (but this behavior can be changed if a variable BASH_ENV exists, which specifies the name of a script to be executed before the non-interactive shell; see man bash)

Here are the implications:

  • Anything that should be available to a script MUST be in ~/.profile, not .bashrc, that is why the PATH should be defined in ~/.profile rather than .bashrc. Another reason, is that scripts using /bin/sh will also read .profile. Ideally, because ~/.profile might be red by /bin/sh, it should only contain stuff NOT specifically related to bash

  • If you launch an application by clicking in a graphical shell (e.g. gnome), the application will only knows about the environment that was created at login. In particular, it will not know about stuff in .bashrc. .

  • ~/.bashrc should contain anything that one might need at an interactive command line, like the prompt, aliases, environment variables for interactive applications.

  • ~/.bashrc is reloaded every time you start a new copy of bash while ~/.profile is loaded only once, at log in (or if you explicitly call bash with the -l option)

Recommendations:

For more information, check out http://mywiki.wooledge.org/DotFiles