在目标机器(OS X El Capitan)上,我brew
有/usr/local/bin
.当我尝试获取brew的路径时,我没有得到结果:
# ssh [email protected] -p 2222 which brew
#
故障排除:
brew
/usr/local/bin/
通过以下方式正确执行ssh
:# ssh [email protected] -p 2222 ls -l /usr/local/bin/brew -rwxr-xr-x 1 vagrant admin 656 Mar 20 10:05 /usr/local/bin/brew # ssh [email protected] -p 2222 /usr/local/bin/brew --version Homebrew 0.9.5 (git revision 3a41; last commit 2016-03-20)
/usr/local/bin
路径中有:# ssh [email protected] -p 2222 echo $PATH /usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/opt/local/bin:/opt/local/sbin
which
本身似乎没有问题:# ssh [email protected] -p 2222 which bash /bin/bash
此外,当以交互方式记录到机器时,我得到了预期的结果:
# ssh [email protected] -p 2222 Last login: Sun Mar 20 12:02:55 2016 from 10.0.2.2 osx-pf:~ vagrant$ which brew /usr/local/bin/brew
最后
which brew
在命令替换表达式中起作用:# ssh [email protected] -p 2222 echo $(which brew) /usr/local/bin/brew
echo
在之前调用which brew
会导致它给出正确的结果:# ssh [email protected] -p 2222 echo test ; which brew test /usr/local/bin/brew
显式调用 shell 来运行
which brew
并不会改变这种情况:# ssh [email protected] -p 2222 /bin/sh -c "which\ brew" # ssh [email protected] -p 2222 /bin/sh -c "which\ which" /usr/bin/which
然而,显式调用
/bin/sh
(6) 中的“技巧”不再有效:# ssh [email protected] -p 2222 /bin/sh -c "echo\ test\ \;\ which\ brew" test #
为什么which brew
直接作为 ssh 命令参数运行会失败?
为什么echo
哪个外部命令/bin/echo
看到正确PATH
而看which
不到?为什么按顺序运行两个命令会导致第二个命令使用第一个命令的环境?
是否可以确保在不参考(6)中未记录的(我认为)解决方法的情况下加载环境?
答案1
ssh [email protected] -p 2222 echo $PATH
您的本地系统PATH
将在此处打印。您应该引用该变量以防止它被本地 shell 扩展:
ssh [email protected] -p 2222 'echo $PATH'
这同样适用于:
ssh [email protected] -p 2222 echo $(which brew)
至于:
ssh [email protected] -p 2222 echo test ; which brew
which brew
在 SSH 命令结束后由本地 shell 运行。这就是为什么这不起作用:
ssh [email protected] -p 2222 /bin/sh -c "echo\ test\ \;\ which\ brew"
旁注:您不需要执行所有转义操作。
这里的问题可能是您要添加brew
到您的PATH
in .profile
(或.bash_profile
或一些类似的文件)中,该文件在登录外壳已开始。 SSH 仅在交互运行时启动登录 shell,而不是在被告知运行命令时启动。从man ssh
:
If command is specified, it is executed on the remote host instead of a login shell
你可以尝试:
ssh [email protected] -p 2222 bash -lc brew
答案2
当您直接从 ssh 运行命令时,您并不是“登录”,而只是运行命令。
一些 shell 脚本在您“登录”时运行 - ~/.bashrc、/etc/profile 等。
which
使用环境变量 - 特别是$PATH
- 可以在这些脚本之一中设置。没有$PATH
,which
将不知道去哪里寻找。
另外,不会给你你所期望的 -在它到达 ssh 之前由 shell 解释 - 比较:与(注意 shell 扩展周围的单引号)。第一个将获取本地主机名,将其发送到远程主机进行回显。第二个将(字面意思)发送到远程 shell,并在那里进行扩展。ssh [email protected] -p 2222 echo $(which brew)
$(which brew)
ssh [email protected] -p 2222 echo $(hostname)
ssh [email protected] -p 2222 echo '$(hostname)'
$(hostname)
更新:我对此略有错误。
当您通过 ssh 运行命令时,ssh 会判断是否需要 shell(例如计算变量等)。如果不需要,则立即运行二进制程序。否则运行 bash,这可能会设置环境变量等。
这就是为什么(在你的评论中)brew --version 失败 - 你没有提到路径。当您 时echo...; brew --version
,分号;
是一个特殊的 shell 字符; ssh 通过运行 bash 来为您处理这个问题。