2

My problem is

$ ssh localhost fswatch          
bash: fswatch: command not found

when without SSH command (i.e. fswatch) works fine.

I found that PATH in SSH session is default Mac's

$ ssh localhost echo \$PATH        
/usr/bin:/bin:/usr/sbin:/sbin

since without SSH

$ echo $PATH
/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

I really do not remember how have I set up the PATH, but sure ~/.bashrc and ~/.bash_profile do not edit PATH variable. There is a config file /etc/paths:

$ cat /etc/paths         
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

Homebrew, npm, pip usually install programs to /usr/local/bin, so all installed programs are there and I can't access them via ssh localhost command on my MacOS. There is no problem with Linux.

So my question is how to configure OpenSSH to use PATHs from /etc/paths and /etc/paths.d?

I also tried to hack:

$ ssh localhost sh -lc 'echo empty;echo $PATH'

/usr/bin:/bin:/usr/sbin:/sbin
$ ssh localhost bash -lc 'echo empty;echo $PATH'

/usr/bin:/bin:/usr/sbin:/sbin

first line is always empty, don't you know why?

And my final workaround

$ ssh localhost bash -lc ':; 
    export PATH="$( cat /etc/paths /etc/paths.d/* | tr \\\\n : )"; 
    echo $PATH; 
    fswatch --version'
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/VMware Fusion.app/Contents/Public
fswatch 1.14.0
Copyright (C) 2013-2018 Enrico M. Crisostomo <enrico.m.crisostomo@gmail.com>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Enrico M. Crisostomo.

Here first :; is important because first command is somehow dropped from execution

System: MacOS Mojave 10.14.5
ssh -V: OpenSSH_7.9p1, LibreSSL 2.7.3
bash --version GNU bash, version 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

5
  • Try su -l login -c ... with your login name.
    – harrymc
    Aug 21 '20 at 6:43
  • I am not clear what do you want different from your "final workaround". Would an alias be enough? Aug 23 '20 at 11:47
  • No. I'd like to configure SSH server.
    – kyb
    Aug 23 '20 at 13:13
  • What happens when you do ssh -t localhost fswatch instead of ssh localhost fswatch ? Aug 27 '20 at 7:50
  • ~ ❯❯❯ ssh localhost fswatch bash: fswatch: command not found ~ ❯❯❯ ssh -t localhost fswatch bash: fswatch: command not found Connection to localhost closed. ~ ❯❯❯
    – kyb
    Aug 27 '20 at 7:52
2
+50

You can configure the SSH server to give clients a customized environment, including a custom PATH variable. You will need to configure 2 things:

  1. Create the file ~/.ssh/environment on the server containing the following:

    PATH=/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    
  2. Change the SSH server config file /private/etc/ssh/sshd_config to include the following line:

    PermitUserEnvironment PATH,LANG
    

Finally, restart/reload the SSH daemon on the server. SSH login clients should have access to your customized environment!

2
  • This can have severe security implications, see man sshd_config -> PermitUserEnvironment
    – dirdi
    Aug 26 '20 at 13:59
  • It is dangerous. So it would be better PermitUserEnvironment PATH,LANG
    – kyb
    Aug 26 '20 at 18:06
0

On my system I can just edit .bashrc and put this at the very top:

PATH=/my/path:$PATH

It is important to put it before:

# If not running interactively, skip the rest
[ -z "$PS1" ] && return
-2

For my answer I assume you are using the Bourne Again SHell, but the following is true for most other shells as well:

The reason for the observed behavior is, that your command will not run in an interactive but a non-interactive shell:

When the user's identity has been accepted by the server, the server either executes the given command in a non-interactive session or, if no command has been specified, logs into the machine and gives the user a normal shell as an interactive session. All communication with the remote command or shell will be automatically encrypted.

- $ man ssh

I suspect that somewhere inside your .bashrc you extend your PATH variable. But BASH will not interpret your .bashrc file if you do not run an interactive shell:

When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist.

- $ man bash

So the easiest solution to this problem is to just provide the full path to the executable, like: $ ssh localhost /full/path/to/fswatch This is the most stable and secure solution to this problem and will always work!

When you connect to localhost you can leverage the which command: $ ssh localhost $(which fswatch). However, this will most probably not work, when you connect to another host.

Another, possible way would be to manipulate the PATH environment variable of the remote host for non-interactive shells (see @hedgie's answer). However, this poses security implications and therefore should not be used in production:

Enabling environment processing may enable users to bypass access restrictions in some configurations using mechanisms such as LD_PRELOAD.

- man sshd_config

7
  • This will not work. which also relies on PATH.
    – kyb
    Aug 26 '20 at 12:04
  • @kyb: Nope. $(which ...) will run locally, even before the connection via ssh is being established. Read up manpages.debian.org/buster/bash/… And for the third time: I do not recommend using which but using the full path to the executable. The which part is only an example to automate this, if you connect to localhost. If you connect to another location you cannot use which but have to manually provide the full path.
    – dirdi
    Aug 26 '20 at 12:39
  • ssh localhost which fish returns nothing, but this ssh localhost env PATH=\$PATH:/usr/local/bin which fish returns /usr/local/bin/fish
    – kyb
    Aug 26 '20 at 12:43
  • Do not run ssh localhost which fish but ssh localhost $(which fish) !
    – dirdi
    Aug 26 '20 at 12:44
  • 1
    Ahah ). What if I am connecting to remote host with different PATHs. I.e from linux to mac.
    – kyb
    Aug 26 '20 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.