Historically, the profile files (/etc/profile
and ~/.profile
) were invoked when you logged in (on the text console, what else?) and served many purposess:
- Set environment variables and other parameters (e.g. umask) for the session.
- Run extra programs at the start of the session (e.g. email notification).
- Run the program for the session, if different from the shell (e.g. another shell or X Window).
- Set terminal parameters (e.g.
stty
).
- Set shell parameters (e.g. aliases).
All these purposes weren't identified as separate until later. Because the profile scripts may do things that only make sense in an interactive session (terminal interaction, start other programs), when remote shell invocation (rsh) was introduced, the makes of rsh decided not to invoke the remote shell as a login shell, so that the profile scripts aren't executed. (Some versions of rshd
have an option to run the remote shell as a login shell.) Ssh copied this behavior in order to be a drop-in replacement for rsh.
If you want to have your profile scripts executed, you can invoke them explicitly.
ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'
Note the command .
to load the profile scripts inside the shell: they are commands to be executed inside that shell, not an external program.
If you want to set an environment variable globally for all users, there is another method on many systems: instead of defining it in /etc/profile
, define it in /etc/environment
. This file is read through the pam_env
module; most Linux distributions are set up to read it.
If your login shell is bash, there is a further possibility. Normally, you should not set environment variables in .bashrc
(because they won't be set in X sessions except if you go through a terminal with an interactive shell, because they won't be set if you log in interactively on a text console or over ssh, because they'll override custom settings if you invoke a shell inside another program). However, bash has a strange feature that I've never understood: it reads ~/.bashrc
in two unrelated circumstances:
- in interactive shells that are not login shells;
- in non-interactive shells that are not login shells, if bash thinks it has been invoked by
rshd
or sshd
.
When you run a command over ssh, you are in the second case. You can arrange to have your profile read by reading /etc/profile
and .profile
from .bashrc
. Include the following code in your ~/.bashrc
:
case $- in
*i*) :;; # this is an interactive shell, fine
*) # This is not an interactive shell! This must be a non-interactive remote shell session.
. /etc/profile; . ~/.profile
return;;
esac
ydisplay
work? doesssh 127.0.0.1 /usr/app/cpn/bin/ydisplay
work?ssh 127.0.0.1 echo $PATH
does not do what you might think it does: the shell expands $PATH before ssh is even executed, so that doesn't prove or disprove anything.