How a bash shell starts up under Unix and Linux
Interactive, login shell
Roughly speaking, an interactive login shell is what is invoked when you open up a new terminal window.
In order, the following files are loaded
/etc/profile
And first one found of ~/.bash_profile, ~/.bash_login, ~/.profile
At exit,
~/.bash_logout
Interactive, non-login shell
Roughly speaking, an interactive, non-login shell is what you get when you type ‘bash’ or ‘su’ at the command prompt, or a file has something similar to ‘#!/bin/bash’ at the top.
An interactive, non-login shell inherits the parent shell environment.
In order, the following files are loaded
~/.bashrc
Remote shell and remote shell commands
A remote shell is one started up by rshd or ssh where you then interact at the prompt. The normal rules for an interactive, login shell apply.
In order, the following files are loaded
~/.bashrc
A remote shell command is a command similar to:
ssh me@10.1.10.123 "ls"
A remote shell command does not inherit any environment.
In order, the following files are loaded
~/.bashrc
/etc/bashrc
/etc/bashrc is not a standard part of the bash startup sequence. However, by convention, most bash distributions include something similar to
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
either in /etc/profile or in ~/.bashrc. This loads the content of /etc/bashrc.
What do you include where?
Conventional advice says:
- Environment settings go in /etc/profile (global) or ~/.bash_profile, ~/.bash_login, ~/.profile (local)
- Functions, aliases etc. go in /etc/bashrc or ~/.bashrc
As far as this goes, I agree, but it’s not complete. This incompleteness is the main reason for this note. Remember
- Remote shell commands do not inherit any of the custom environment settings (no parent shell!)
So, if you want a standalone ‘ssh’ command to function correctly, and see all your custom PATH settings and other environment settings, you need to ensure the environment is loaded.
What I’ve done is to bracket my environment settings in a conditional statement, and invoke them from ~/.bashrc.
# My environment file - e.g. ~/.bash_profile
if [[ ${my_environment_loaded:-false} == false ]]
then
... (set your environment here)
my_environment_loaded=true
fi
and in ~/.bashrc, modify the standard format
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
to something similar to
if [ -f /etc/bashrc ]; then
. /etc/bashrc
. ~/.bash_profile
fi