135
votes

I can't seem to set a new $PATH such that it is used when executing commands via ssh user@host command. I have tried adding export PATH=$PATH:$HOME/new_path to ~/.bashrc and ~/.profile on the remote machine, but executing ssh user@host "echo \$PATH" shows that the change has not been picked up (it shows /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games). The remote machine is running Ubuntu 8.04.

I'm sure I could hack it into /etc/profile, but that's not a clean solution and it only works when one has root access.

6
I have tried adding export PATH=$PATH:$HOME/new_path to both ~/.bash_login and ~/.bash_profile (in addition to the previously-tried ~/.bashrc and ~/.profile). Neither works. In both cases I had to create the file.Denver Gingerich
In my particular use case, it is not easy to modify the command sent to ssh. I am using stfufs (guru-group.fi/too/sw/stfufs), which constructs the ssh command itself. I realize its method is not a great solution, but it would be nice to fix it without modifying stfufs.Denver Gingerich
You could put an ssh wrapper in stfufs' way, call the real ssh with modified args, if that's easierHasturkun

6 Answers

187
votes

As grawity said, ~/.bashrc is what you want, since it is sourced by non-interactive non-login shells.

I expect the problem you're having has to do with the default Ubuntu ~/.bashrc file. It usually starts with something like this:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

You want to put anything for non-interactive shells before this line.

30
votes

Do you have an ~/.bash_login or ~/.bash_profile?

Bash in interactive mode checks for these files, and uses the first existing one, in this order:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

So if you have an ~/.bash_profile, then whatever changes you do to ~/.profile will be left unseen.

Bash in non-interactive mode sometimes reads the file ~/.bashrc (which is also often source'd from the interactive scripts.) By "sometimes" I mean that it is distribution-dependent: quite oddly, there is a compile-time option for enabling this. Debian enables the ~/.bashrc reading, while e.g. Arch does not.

ssh seems to be using the non-interactive mode, so ~/.bashrc should be enough. When having problems like this, I usually add a few echo's to see what files are being run.

20
votes

ssh documentation says:

If command is specified, it is executed on the remote host instead of a login shell.

which is why adding to the bashrc files doesn't work. you do however have the following options:

  1. If the PermitUserEnvironment option is set in the sshd config, you can add your PATH setting to ~/.ssh/environment

  2. ssh remotemachine 'bash -l -c "somecommand"'

8
votes

You can always say:

ssh remotemachine 'export PATH=wedontneedastinkingpath; echo $PATH'
2
votes

In addition to @signpolyma answer, you will have to add your export before these lines

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
2
votes

Just had the same problem myself, solved it with:

ssh user@remotehost PATH=\$HOME/bin:\$PATH\; remote-command