Alex Garbiak
← Lib

Bash Config Setup

Updated bashshellsetupgit-bashcheatsheet

A general-purpose baseline for now — the plan is to trim this down to the setup I actually use, and drop the rest.

Bash reads a different startup file depending on how the shell was started — login vs non-login, interactive vs non-interactive. Most day-to-day confusion (aliases or PATH changes that “don’t work” in a new terminal) comes from putting config in the wrong file for the shell type actually being launched.

The config files

FileRead by
/etc/profileEvery login shell, system-wide, before any per-user file.
~/.bash_profileAn interactive login shell — checked first.
~/.bash_loginUsed only if ~/.bash_profile doesn’t exist.
~/.profileUsed only if neither of the above exists (also read by sh and other POSIX shells).
~/.bashrcAn interactive non-login shell (e.g. a new terminal tab, or a shell opened from inside another shell).
/etc/bash.bashrcSystem-wide equivalent of ~/.bashrc, read before it.
~/.bash_logoutRun when an interactive login shell exits.
$BASH_ENV fileA non-interactive shell (e.g. a script), if that variable is set — otherwise no startup file is read at all.

Login vs non-login, interactive vs non-interactive

Shell typeExampleFile Bash reads
Login, interactiveSSH-ing into a machine; a fresh Git Bash window (with -l)/etc/profile, then the first of ~/.bash_profile / ~/.bash_login / ~/.profile
Non-login, interactiveA new terminal tab in an already-logged-in desktop session/etc/bash.bashrc, then ~/.bashrc
Non-login, non-interactiveA shell script, a cron job$BASH_ENV, if set — nothing otherwise

Crucially, login shells do not automatically read ~/.bashrc — that’s why aliases defined only in ~/.bashrc can seem to vanish in a login shell (e.g. over SSH) even though they work fine in every new terminal tab.

The standard fix: source .bashrc from .bash_profile

The common convention is to keep all actual configuration in ~/.bashrc, and make ~/.bash_profile just source it — so login shells pick it up too:

# ~/.bash_profile
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

With this in place, it doesn’t matter which file a given shell reads first — the same config always ends up loaded.

Git Bash specifics

Git for Windows’ Bash behaves like a standard login shell by default, which is why ~/.bash_profile (not ~/.bashrc) is the file that actually runs when you open a fresh Git Bash window — unless it sources ~/.bashrc as above.

  • Git Bash’s $HOME is C:\Users\<you> — the same files apply as on Linux/macOS, just under that path.
  • If neither ~/.bash_profile nor ~/.profile exists, Git Bash falls back to its own built-in /etc/profile, which already sources /etc/bash.bashrc and sets up a reasonable PATH — creating ~/.bash_profile is what lets you extend that instead of replacing it.
  • Terminal appearance (fonts, colors, keyboard shortcuts) is a separate layer handled by mintty, not Bash — see Git Bash for Windows Setup.

What typically goes in .bashrc

CategoryExample
Aliasesalias ll='ls -la'
PATH additionsexport PATH="$HOME/.local/bin:$PATH"
Environment variablesexport EDITOR=vim
Prompt customizationexport PS1='\u@\h:\w\$ '
Functionsmkcd() { mkdir -p "$1" && cd "$1"; }
Sourcing extra files[ -f ~/.git-completion.bash ] && . ~/.git-completion.bash

Applying changes

Edits to .bashrc or .bash_profile don’t take effect in windows that are already open.

CommandDescription
source ~/.bashrcRe-run the file in the current shell.
. ~/.bashrcEquivalent shorthand — . is the POSIX form of source.
Open a new terminal windowSimplest option; picks up whichever file applies to that shell type.