Bash configuration#

bash is our default shell, but we use fish for all interactive purposes. The bash setup is modular to achieve the following outcomes

  • bashrc drives the config, with separate files for setting various pices of config such that the separate scripts “look” similar in structure to our fish counterparts.

  • Machine-specific customization is overlayed via os and user sepcific files in a declarative manner.

  • Exactly which os and which user file gets included is determined via chezmoi generated symlinks.

Directory layout#

Show layout
home/dot-bash#
$ lsd --almost-all --tree home/dot-bash
dot-bash
├── bash_profile
├── bashrc
├── bashrc-lib.sh
├── bashrc.d
│   ├── bashrc-fzf.sh
│   └── bashrc-git.sh
├── completions
│   └── mg.bash
├── generated
│   └── fzf-fragments.sh.tmpl
├── overlays
│   ├── bashrc-linwin.sh
│   ├── bashrc-os-linux-arch.sh
│   ├── bashrc-os-linux-ubuntu.sh
│   ├── bashrc-os-linux.sh
│   ├── bashrc-os-uncharted.sh
│   ├── bashrc-os-windows.sh
│   ├── bashrc-user-vvnraman.sh
│   ├── bashrc-wsl2.sh
│   ├── no-op.sh
│   ├── symlink_bashrc-os-config.sh.tmpl
│   └── symlink_bashrc-user-config.sh.tmpl
├── profile
└── tests
    ├── git-shell-bare-siblings.bats
    ├── git-shell-common.bash
    ├── git-shell-default-layout.bats
    ├── git-shell-parent-bare-siblings.bats
    ├── run-bats-bash.sh
    └── run-bats-fish.sh

Load order#

Implicit Bash startup behavior

  • Login bash reads .bash_profile (or .bash_login / .profile).

  • Interactive non-login bash reads .bashrc.

Our explicit startup order is the following:

  1. bash_profile loads profile

    bash_profile#
    1# vim: set filetype=sh : */
    2
    3source ~/.profile
    
  2. profile loads bashrc

    profile#
     1# vim: set filetype=sh : */
     2# ~/.profile: executed by the command interpreter for login shells.
     3# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
     4# exists.
     5
     6# We primarily use this file to do 2 things
     7# - setup the PATH correctly.
     8# - setup prompt
     9# All the customizations occur in the `bashrc-custom` files.
    10
    11# if running bash
    12if [[ -n "$BASH_VERSION" ]] && [[ -f "$HOME/.bashrc" ]]; then
    13  # shellcheck disable=SC1090,SC1091
    14  . "$HOME/.bashrc"
    15fi
    

Explicit order inside bashrc#

  1. bashrc loads .sh scripts from bashrc.d/ directory

  2. bashrc loads overlays/bashrc-linwin.sh

  3. bashrc loads OS and user specific overlays

    bashrc#
    57if [[ -d "${HOME}/dot-bash/bashrc.d" ]]; then
    58    for script in "$HOME/dot-bash/bashrc.d/"*.sh; do
    59        # shellcheck disable=SC1090
    60        [[ -f "${script}" ]] && source "${script}"
    61    done
    62fi
    63
    64# shellcheck disable=SC1090,SC1091
    65[[ -f "${HOME}/dot-bash/overlays/bashrc-linwin.sh" ]] && source "${HOME}/dot-bash/overlays/bashrc-linwin.sh" # Common for Linux & Windows
    66
    67# These come later as they can be used to override anything done before
    68# shellcheck disable=SC1090,SC1091
    69[[ -f "$HOME/dot-bash/overlays/bashrc-user-config.sh" ]] && source "$HOME/dot-bash/overlays/bashrc-user-config.sh" # symlinks
    70# shellcheck disable=SC1090,SC1091
    71[[ -f "$HOME/dot-bash/overlays/bashrc-os-config.sh" ]] && source "$HOME/dot-bash/overlays/bashrc-os-config.sh" # symlinks
    
  4. Linux distro agnostic config is present in dot-bash/overlays/bashrc-os-linux.sh, which gets loaded by the distro specific bash config symlinked via chezmoi template dot-bash/overlays/symlink_bashrc-os-config.sh.tmpl.

    bashrc-os-linux-arch.sh#
    1# Arch Linux config
    2
    3# shellcheck disable=SC1091
    4source "$HOME/dot-bash/bashrc-lib.sh" # common functions
    5
    6# shellcheck disable=SC1090
    7[[ -f "${HOME}/dot-bash/overlays/bashrc-os-linux.sh" ]] && source "${HOME}/dot-bash/overlays/bashrc-os-linux.sh"
    8
    9export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
    
    bashrc-os-linux-ubuntu.sh#
     1# Ubuntu config
     2
     3# shellcheck disable=SC1091
     4source "$HOME/dot-bash/bashrc-lib.sh" # common functions
     5
     6# shellcheck disable=SC1090
     7[[ -f "${HOME}/dot-bash/overlays/bashrc-os-linux.sh" ]] && source "${HOME}/dot-bash/overlays/bashrc-os-linux.sh"
     8
     9# Load WSL2 config conditionally
    10if is_wsl2; then
    11  # shellcheck disable=SC1090
    12  [[ -f "${HOME}/dot-bash/overlays/bashrc-wsl2.sh" ]] && source "${HOME}/dot-bash/overlays/bashrc-wsl2.sh"
    13fi
    

Relevant changelogs#