If you've ever tried to change system-wide bash settings, you know there are three major ways of invoking bash, all of which behave differently when reading in settings files.
- Interactive login shell (e.g., when logging in from the console or via ssh)
- Interactive non-login shell (e.g., when you run bash at a terminal prompt)
- Non-interactive shell (e.g., to run a shell script)
An interactive shell has both input and output connected to a tty (usually the user's terminal). If you type echo $- and the value contains i, the shell is interactive. (The other letters are options passed in at invocation, or via the set builtin.) A login shell is started with the --loginoption. This is usually handled by whatever program you're using for login.
An interactive login shell looks for and executes files in this order:
/etc/bash_profile, ~/.bash_profile, ~/.bash_login, ~/.profile
A non-login shell, on the other hand, reads only from
~/.bashrcTo avoid editing multiple files, users should have this in their ~/.bash_profile:
if [ -f ~/.bashrc ]; then source ~/.bashrc fi
But what about system-wide settings? A non-login shell won't read from /etc/profile, but it will inherit environment settings from the shell that invoked it, which if you go far enough back up the chain, will be a login shell. So system-wide environment settings can go in /etc/profile. Put other settings (e.g., aliases) in /etc/bashrc, then add this section to each user's ~/.bashrc:
if [ -f /etc/bashrc ]; then source /etc/bashrc fi
Juliet Kemp has been messing around with Linux systems, for financial reward and otherwise, for about a decade. She is also the author of "Linux System Administration Recipes: A Problem-Solution Approach" (Apress, 2009).