lichtung

which bash startup file runs, and when

· #footguns #systems

Bash decides which startup files to read from how it was started, and the three cases barely overlap — which is why environment variables keep going missing in exactly the place you didn't test.

Login shell. Started at a console login, by bash -l, or by ssh host with no command. It reads /etc/profile, then the first that exists of ~/.bash_profile, ~/.bash_login, ~/.profile, and stops at the first one it finds. It does not read ~/.bashrc unless one of those files sources it.

Interactive, non-login. A new terminal window or tab on most Linux setups, or plain bash. It reads ~/.bashrc (and, on many distros, /etc/bash.bashrc). It does not touch the profile files.

Non-interactive. Running a script (bash script.sh), or ssh host 'some command'. It reads neither the profile chain nor ~/.bashrc. The only hook is $BASH_ENV: if that's set, bash sources the file it names, and nothing else.

The traps live in the gaps:

The convention that sidesteps all of it: keep environment — PATH, exports — in ~/.profile or ~/.bash_profile; keep interactive niceties — aliases, prompt, completion — in ~/.bashrc; and have ~/.bash_profile source ~/.bashrc so a login shell gets both. One place for "always", one for "interactive", and you stop guessing which file a given invocation will read.