我有一个用户没有对任何点文件中的 $PATH 进行任何修改:它正是系统默认设置。从登录 shell:
$ ssh example.com
[email protected]:~$ cat /tmp/hello.hs
#!/bin/bash
echo "$SHELL"
echo "$PATH"
[email protected]:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin
正如在 中指定的/etc/profile
。我发现这相当出乎意料:
$ ssh example.com '/tmp/hello.sh'
/bin/bash
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
~/.bashrc
就像我说的,在和 中都没有修改 $PATH /etc/bash.bashrc
。也没有~/.ssh/environment
。ssh(1)
声明环境变量PATH
是
设置为默认 PATH,如编译 ssh 时所指定的。
但此主题来自 StackOverflow 和这个邮件列表这篇文章建议我应该只需修改 /etc/profile(其中一个 shell 启动文件等)即可影响给定命令的 $PATH。
这里发生了什么?
答案1
来自ssh(1)
手册页:“如果指定了命令,它将在远程主机上执行,而不是在登录 shell 上执行。”
简而言之,当您实际登录到计算机时,bash 将作为登录 shell 启动并加载适当的文件,当您远程连接并发出命令时,它将代替 bash 运行,这意味着这些文件不会加载。您可以su -l -c
在 ssh 的命令部分使用或类似命令来解决此问题。
在某些情况下,我也看到了-t
ssh 工作(分配 tty)的参数。
编辑1:
我认为您找到的 PATH 信息表明,默认路径(除非我们覆盖它)是编译到 sshd 中的路径。我确保我的 /etc/profile、/etc/bash*、本地点文件等没有任何 PATH 信息,然后我登录时仍然有 PATH。我在 sshd 中搜索了这个并在那里找到了它。所以手册页是这样说的:
ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
然后我将其添加PATH=$PATH:/my/test
到远程文件的最顶部.bashrc
,并再次检查:
ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test
所以我绝对可以影响它,并且默认 PATH 是编译到 sshd 中的那个。:)
答案2
通过运行以下命令,我能够让 ssh 使用远程路径运行命令:
ssh dist@d6 "bash --login -c 'env'"
这里,env 可以替换为您所需的任何命令。
我已经授权密钥,因此不需要密码来运行命令或 ssh。
答案3
我想出了一个不同的解决方案来解决这个问题。我个人的偏好是创建新的配置文件,而不是更改现有的配置文件。这样我可以更轻松地从默认配置中排除更改。
以下是 的内容/etc/profile.d/ssh_login.sh
:
#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
. /etc/environment
fi
使用dropbear
代替openssh-server
(这也应该适用于 openssh),当我远程登录时,SSH_CONNECTION 变量会自动设置。我创建了一个新的 shell 配置文件配置来检测 SSH 登录,在屏幕上显示一些信息,最重要的是,从中加载全局环境设置/etc/environment
以替换编译的值。请注意,这只会影响交互式 SSH shell,而不会影响远程命令执行。
或者,如果您使用 openssh 并且始终想要加载全局环境,无论它是否是交互式 shell,您都可以~/.ssh/
像这样放置符号链接:
ln -s /etc/environment ~/.ssh/environment
然后您需要启用PermitUserEnvironment
中的选项/etc/sshd/sshd_config
。但请仅对受信任的用户执行此操作,因为这可以使他们使用 LD_PRELOAD 等机制绕过某些配置中的访问限制。请参阅了解man sshd_config
更多信息,特别是如何使用Match
块将选项限制到特定用户/组。
答案4
如果您想要加载配置文件路径,请尝试:
#!/bin/bash -i
在脚本顶部。这样,运行脚本时,shell 处于交互模式。
当 bash 作为交互式登录 shell 或使用 --login 选项作为非交互式 shell 调用时,它首先从文件 /etc/profile 中读取并执行命令(如果该文件存在)。读取该文件后,它会按顺序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,然后从第一个存在且可读的文件中读取并执行命令。启动 shell 时可以使用 --noprofile 选项来禁止此行为。