我的问题是
$ ssh localhost fswatch
bash: fswatch: command not found
当没有 SSH 命令(即 fswatch)时工作正常。
我发现 SSH 会话中的 PATH 是 Mac 的默认路径
$ ssh localhost echo \$PATH
/usr/bin:/bin:/usr/sbin:/sbin
因为没有 SSH
$ echo $PATH
/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
我真的不记得我是如何设置 PATH 的,但请确保~/.bashrc
不要~/.bash_profile
编辑 PATH 变量。有一个配置文件/etc/paths
:
$ cat /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
Homebrew、npm、pip 通常会将程序安装程序到/usr/local/bin
,因此所有已安装的程序都在那里,我无法通过ssh localhost command
我的 MacOS 访问它们。Linux 没有问题。
所以我的问题是如何配置 OpenSSH 以使用来自/etc/paths
和的PATH/etc/paths.d?
我也尝试破解:
$ 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
第一行总是空的,你不知道为什么吗?
我的最终解决方法
$ 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 <[email protected]>.
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.
这里第一个:;
很重要,因为第一个命令以某种方式从执行中删除
系统: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)
答案1
您可以配置 SSH 服务器,为客户端提供自定义环境,包括自定义PATH
变量。您需要配置以下两项:
~/.ssh/environment
在服务器上创建包含以下内容的文件:PATH=/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
更改 SSH 服务器配置文件
/private/etc/ssh/sshd_config
以包含以下行:PermitUserEnvironment PATH,LANG
最后,重新启动/重新加载服务器上的 SSH 守护程序。SSH 登录客户端应该可以访问您的自定义环境!
答案2
在我的系统上我只需编辑.bashrc
并放入在最顶端:
PATH=/my/path:$PATH
将其放在前面很重要:
# If not running interactively, skip the rest
[ -z "$PS1" ] && return
答案3
对于我的回答,我假设您使用的是 Bourne Again SHell,但以下情况也适用于大多数其他 shell:
观察到的行为的原因是,您的命令不会在交互式 shell 中运行,而是在非交互式 shell 中运行:
当用户的身份被服务器接受后,服务器要么在非交互式会话中执行给定的命令,要么在未指定命令的情况下登录到计算机并为用户提供常规 shell 作为交互式会话。所有与远程命令或 shell 的通信都将自动加密。
-$ man ssh
我怀疑你在你的文件内部的某个地方.bashrc
扩展了你的变量。但是如果你不运行交互式 shell,PATH
BASH 将不会解释你的文件:.bashrc
什么时候启动一个非登录 shell 的交互式 shell 时,bash 将从 /etc/bash.bashrc 和 ~/.bashrc 读取并执行命令(如果这些文件存在)。
-$ man bash
因此,解决此问题最简单的方法就是提供可执行文件的完整路径,例如:$ ssh localhost /full/path/to/fswatch
这是解决此问题最稳定、最安全的方法,并且始终有效!
当您连接到时,localhost
您可以利用以下which
命令:$ ssh localhost $(which fswatch)
。但是,当您连接到另一台主机时,这很可能不起作用。
另一种可能的方法是操纵PATH
远程主机的环境变量以用于非交互式 shell(请参阅 @hedgie 的回答)。但是,这会带来安全隐患,因此不应在生产中使用:
启用环境处理可能会使用户能够使用 LD_PRELOAD 等机制绕过某些配置中的访问限制。
-man sshd_config