Bash config and where it lives

Bash is one of the most commonly used Linux shells, however if you're new to bash it's not always obvious which configuration file you should use when adding custom configuration. This post is going to go over which configuration files bash reads, and when.

Bash configuration

When you start a new bash shell, bash will look in several different locations for configuration files. Configuration files can contain anything you can normally type into bash, for example you might want to set up some command aliases, or environment variables:

# Add ~/bin to path
export PATH="$PATH:~/bin"

# Set default editor to vim
export VISUAL=vim

# Set aliases
alias ls='ls --color=auto'
alias ll='ls -l --color=auto'

Login and interactive shells

If bash is started by a login process (e.g. by /bin/login) the first argument by convention is prefixed with a - character:

$ echo $0
-bash

Bash uses this to determine if the shell should be treated as a login shell. Bash then checks to see if the shell is interactive, this is done by calling isatty to check stdin and stderr are connected to a tty. There are a few exceptions to this, for example using the -c option will normally prevent bash running as an interactive shell. For more info on the other exceptions, refer to the bash docs.

Bashrc and profile config

Once bash has checked to see if it's being run as a login or interactive shell, it decides which config files to load as follows:

Flow diagram showing which config bash reads at startup

Profile configuration is loaded from /etc/profile, if the file exists. And then from one of the following files:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

The files in ~ are checked in order, so ~/.bash_login will only be read if ~/.bash_profile is missing, and ~/.profile will only be read if both ~/.bash_profile and ~/bash_login are missing. Bashrc configuration is slightly more straightforward, it's simply read from ~/.bashrc if the file exists.

Sourcing other files

In theory if you start a new login shell, bash will not attempt to read ~/.bashrc. However in reality bash configuration normally sources other configuration. The diagrams below show which files are normally read on CentOS for a user with default bash configuration:

Flow diagram showing the order bash config is loaded on CentOS

Note: the files in /etc/ are global and will be read by all users including root; whereas the files in ~/ are obviously user specific.

Logout config

As well as loading config during startup, bash can also be configured to run commands on exit. To do this configuration should be put in ~/.bash_logout. Like profile config, this config is only used by login shells, however unlike profile configuration you cannot force bash to read the configuration with the -l option.

Exceptions and special cases

There are a few exceptions and special cases which are worth knowing about:

  • Command line options: several command line options such as --norc, --noprofile and --login can be used to alter bash's default behaviour.
  • Running as sh: if bash is invoked as sh it will try to emulate the Bourne shell.
  • Environment variables: BASH_ENV can be used to specify additional config for non-interactive shells.

Full details on the points above can be found in the Bash docs.