bash
recognizes three shell states:
- login shell - shell instance that has been invoked directly by logging in to the server via eg. ssh or text console
- interactive shell - any shell where you can type commands, eg. shell started in graphical terminal. Login shell is also (usually) an interactive shell.
- non-interactive shell - this is usually shell invoked from within some program to run another program or command. As the name implies, in non-interactive shell there is no interaction with the user. For example, if you use ssh to run only a single command on a remote machine (like
ssh host.domain ls -l /etc
) then you are implicitly invoking a non-interactive shell on the remote machine and that shell in turn runs the command, and then quits.
How the startup files work:
- a login shell executes commands from
/etc/profile
(that's the global file for all users) and then looks for files .bash_profile
, .bash_login
or .profile
- in that order - in individual user's home directory, and executes commands from whichever file is found first. Usually by default on a newly created account only the .profile
file exists, and by default it includes commands to execute contents of the .bashrc
file also. However, you can remove the code to run .bashrc
from the .profile
file or you can create any of the other two files with the commands you need, and then .profile
will not be run.
- an interactive (but non-login) shell executes commands from
/etc/bash.bashrc
(that's global for all users) and then from .bashrc
file in the individual user's home directory
- non-interactive shells started locally (ie. from within a program, or by typing
bash
in terminal window) do not run any of these files
- non-interactive shells started from the network (eg. in the above example where you run a command on remote machine via ssh) execute commands from
.bashrc
file in user's home directory only. However, the default .bashrc
file often contains a piece of code at the beginning that stops further execution if the shell is non-interactive.
There are some more subtleties in specific cases, but basically it works as above.
When you connect via VNC and open a terminal, you are executing an interactive non-login shell. When you log in via ssh, you are executing a login shell. Therefore the difference.