Yes, that is the expected behaviour.
The behaviour, in short, is as follows:
- bash started as an interactive login shell: reads
~/.profile
- bash started as an interactive non-login shell: reads
~/.bashrc
Read the bash manual about startup files for more details.
Personally, I think that this behaviour is strange and I have not yet found a rationalization for this design decision.
Some explanation of the terminology:
- An interactive shell is a shell with which you can interact, that means you can type commands in it. Most shells you will use are interactive shells.
- A non-interactive shell is a shell with which you cannot interact. Shell scripts run inside non-interactive shells.
- A login shell is the shell which is started when you login to your system.
- A non-login shell is a shell which is started after the login process.
Most shells you see are interactive non-login shells. This is especially true if you are running a graphical environment like gnome, because then gnome is the "login shell". Any bash session started inside gnome is a non-login shell. If you want to see a real interactive login shell then go to a virtual console (using Ctrl+Alt+F1
) and then log in using your username and password. That is a real interactive login bash shell. You can go back to the graphical shell using Ctrl+Alt+F7
.
There is an option --login
which will make bash behave as if it is a login shell even if started after your have logged in. Configuring gnome-terminal to start bash as a login shell means it will start bash using the --login
option.
Usually you want bash to always read ~/.bashrc
in an interactive shell. Here is how I recommend to do that:
Create a ~/.bash_profile
file. If bash is started as a login shell it will first look for ~/.bash_profile
before looking for ~/.profile
. If bash finds ~/.bash_profile
then it will not read ~/.profile
.
Put the following lines in ~/.bash_profile
:
[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"
Now if bash is started as an interactive login shell it will read the following files:
~/.bash_profile
~/.profile
~/.bashrc
and if bash is started as an interactive non-login shell:
~/.bashrc
You should put stuff which is bash specific in ~/.bashrc
and stuff which is not bash specific in ~/.profile
. For example PATH
goes in ~/.profile
and HISTCONTROL
goes in ~/.bashrc
.
Note that ~/.profile
is not bash specific. Other text based shells (for example sh or ksh) and graphical shells (gnome) also read ~/.profile
. That is why you should not put bash specific stuff in ~/.profile
.
Best Answer
The only real misconception you seem to have is about what constitutes a non-interactive, login shell.
Briefly (see here for more details), with examples:
interactive login shell: You log into a remote computer via, for example
ssh
. Alternatively, you drop to a tty on your local machine (Ctrl+Alt+F1) and log in there.interactive non-login shell: Open a new terminal.
non-interactive non-login shell: Run a script. All scripts run in their own subshell and this shell is not interactive. It only opens to execute the script and closes immediately once the script is finished.
non-interactive login shell: This is extremely rare, and you're unlikey to encounter it. One way of launching one is
echo command | ssh server
. Whenssh
is launched without a command (sossh
instead ofssh command
which will runcommand
on the remote shell) it starts a login shell. If thestdin
of thessh
is not a tty, it starts a non-interactive shell. This is whyecho command | ssh server
will launch a non-interactive login shell. You can also start one withbash -l -c command
.If you want to play around with this, you can test for the various types of shell as follows:
Is this shell interactive?
Check the contents of the
$-
variable. For interactive shells, it will includei
:Is this a login shell?
There is no portable way of checking this but, for bash, you can check if the
login_shell
option is set:Putting all this together, here's one of each possible type of shell: