The confusing Bash configuration files
Posted on wo 11 juli 2018 in dev
This blog is mostly a reminder for my future self, because I always end up forgetting this.
Bash has a bunch of configuration files it parsers through when you fire it up.
Bash reads them in this order (on Fedora, and I suppose RHEL and derivatives too) if invoked as an interactive login shell (i.e. when you log into the system on the console, or through SSH):
/etc/profile(if it exists)~/.bash_profile(if it exists)~/.bash_login(if it exists, and ~/.bash_profile does not exist)~/.profile(if it exists, and if the above two files do not)
When exiting, the interactive login shell executes:
~/.bash_logout(if it exists)/etc/bash.bash_logout(if it exists)
For an interactive non-login shell (that's when you start gnome-terminal or tilix in X or Wayland), Bash just executes ~/.bashrc, if it exists. (So, no, /etc/bashrc is not invoked by Bash itself, but usually through ~/.bashrc, which by default sources /etc/bashrc.)
Because this is odd, the default ~/.bash_profile actually sources ~/.bashrc.
So for an interactive login shell, this happens (assuming the default config files from /etc/skel on Fedora 28):
/etc/profileis read,- whatever is in
/etc/profile.dis included /etc/bashrcis included, and the${BASHRCSOURCED}variable is set to Y~/.bash_profileis read~/.bashrcis sourced through~/.bash_profile/etc/bashrcis sourced, again, this time through~/.bashrc, but it's not actually parsed again, because${BASHRCSOURCED}was already set to Y- neither
~/.bash_login, nor~/.profileare sourced, because~/.bash_profileexists - You get your shell
Finally, when Bash is invoked as the interpreter for a shell script, it will read ${BASH_ENV}, and it will read and execute the filename it finds in there. For Fedora 28, that's /usr/share/Modules/init/bash, owned by the environment-modules package.
Mind that this only happens if the shell script starts with the proper Bash shebang: #!/bin/bash or #!/usr/bin/bash, not with #!/bin/sh. Starting your shell script with #!/bin/sh will yield completely different results, as that will make Bash run in compatibility mode for old(er) shells.