Why does the $PATH of an ssh remote command differ from that of an interactive shell?

I have a user that has made no modifications to the $PATH in any dot-files: it is exactly the system default setting. From a login shell:

$ ssh example.com
[email protected]:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

[email protected]:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Exactly as specified in /etc/profile. This I find rather unexpected:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Like I said, there's no modification of $PATH in ~/.bashrc, nor in /etc/bash.bashrc. No ~/.ssh/environment either. The ssh(1) declares that the environment variable PATH is

Set to the default PATH, as specified when compiling ssh.

but this thread from StackOverflow and this mailing list article suggest that I should be able to influence the $PATH for a given command simply by modifying /etc/profile, one of the shell startup files, etc.

What's going on here?


Solution 1:

From ssh(1) manual page: "If command is specified, it is executed on the remote host instead of a login shell."

So in short when you actually login to the machine bash is started as a login shell and loads the apropriate files, when you connect remotely and issue a command it is run in the place of bash, which means that these files do NOT load. You can work around it with using su -l -c or similar in the command part of ssh.

In some cases I've seen -t argument to ssh work (allocate tty) too.

Edit 1:
I think the PATH information you found, that the default path (unless we override it) is the one compiled into sshd. I made sure that my /etc/profile, /etc/bash*, local dotfiles, etc. didn't have any PATH information in it, then I logged on and still had a PATH. I searched for this one in sshd and found it there. So its how the manpage says:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Then I add PATH=$PATH:/my/test to the very top of my .bashrc file on remote, and check it again:

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

So I can absolutely influence it, and default PATH is the one compiled into sshd. :)

Solution 2:

I was able to get ssh to run commands using the remote path by running:

ssh dist@d6 "bash --login -c 'env'"

Here env can be replaced with what ever command you'd like.

I have authorized keys so didn't need a password to run the command or ssh.