A login shell first reads /etc/profile
and then ~/.bash_profile
.
A non-login shell reads from /etc/bash.bashrc
and then ~/.bashrc
.
Why is that important?
Because of this line in man ssh
:
If command is specified, it is executed on the remote host instead of a login shell.
In other words, if the ssh command only has options (not a command), like:
ssh user@host
It will start a login shell, a login shell reads ~/.bash_profile
.
An ssh command which does have a command, like:
ssh user@host :
Where the command is :
(or do nothing).
It will not start a login shell, therefore ~/.bashrc
is what will be read.
Remote stdin
The supplied tty connection for /dev/stdin in the remote computer may be an actual tty or something else.
For:
$ ssh isaac@localhost
/etc/profile sourced
$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0
$ ls -la /proc/self/fd/0
lrwx------ 1 isaac isaac 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3
$ ls -la /dev/pts/3
crw--w---- 1 isaac tty 136, 3 Dec 24 19:35 /dev/pts/3
Which ends in a TTY (not a network connection) as the started bash sees it.
For a ssh connection with a command:
$ ssh isaac@localhost 'ls -la /dev/stdin'
isaac@localhost's password:
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0
The list of TTY's start the same, but note that /etc/profile was not sourced.
$ ssh isaac@localhost 'ls -la /proc/self/fd/0'
isaac@localhost's password:
lr-x------ 1 isaac isaac 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]
Which tells the shell that the connection is a pipe (not a network connection).
So, in both the test cases, the shell is unable to know that the connection is from a network and therefore does not read ~/.bashrc
(if we only talk about the connection to a network). It does read ~/.bashrc, but for a different reason.