通过 SSH 进入 MacOS 时设置 PATH

通过 SSH 进入 MacOS 时设置 PATH

我的问题是

$ 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 -VOpenSSH_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变量。您需要配置以下两项:

  1. ~/.ssh/environment在服务器上创建包含以下内容的文件:

    PATH=/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    
  2. 更改 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,PATHBASH 将不会解释你的文件:.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

相关内容