~/.profile is typically not read when you run
ssh somecommand, as opposed to an interactive ssh session (or other login method where you start an interactive session).
Ssh supports sending environment variables. In OpenSSH, use the
SendEnv directive in
~/.ssh/config. However the specific environment variable must be enabled with an
AcceptEnv directive in the server configuration, so this may well not work out for you.
OpenSSH also allows setting environment variables on the server side. Again, this must be enabled in the server configuration, here with the
PermitUserEnvironment directive. The variables can be set in the file
~/.ssh/environment. Assuming you use public key authentication, you can also set per-key variables in
environment="FOO=bar" at the beginning of the relevant line.
One thing that I think always works (oddly enough) as long as you're using public key authentication is to (ab)use the
command= option in the
authorized_keys file. A key with a
command option is good only for running the specified command; but the command in the
authorized_keys file runs with the environment variable
SSH_ORIGINAL_COMMAND set to the command the user specified (empty for interactive sessions). So you can use something like this in
~/.ssh/authorized_keys (of course, it won't apply if you don't use this key to authenticate):
if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
else exec \"$SHELL\"; fi" ssh-rsa …
Note that I put line breaks above for legibility, but this actually needs to be all on one line.
Another possibility is to write a wrapper script
~/bin/rsync-wrapper on the server, something like
exec rsync "$@"
--rsync-path='bin/rsync-wrapper' on the
rsync command line. The argument to
--rsync-path is expanded by a shell, so if you prefer you can make the rsync command line self-contained by passing something like
--rsync-path='. ~/.profile; rsync'.
There is another avenue which depends on your login shell being bash or zsh. Bash always reads
~/.bashrc when it's invoked by rshd or sshd, even if it's not interactive (but not if it's called as
sh). Zsh always reads
if [[ $- != *i* ]]; then
# Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
# Not a login shell, but this is an rsh/ssh session