265

如果我 ssh 到机器并运行它,我有一个运行良好的命令,但是当我尝试使用远程 ssh 命令运行它时失败,例如:

ssh user@IP <command>

在不同环境中使用两种方法比较“env”的输出。当我手动登录机器并运行 env 时,我得到的环境变量比运行时多得多:

ssh user@IP "env"

知道为什么吗?

4

6 回答 6

180

有不同类型的贝壳。SSH 命令执行外壳是非交互式外壳,而您的普通外壳是登录外壳或交互式外壳。描述如下,来自 man bash:

       登录 shell 是其参数的第一个字符
       零是 -,或者以 --login 选项开头。

       交互式外壳是在没有非选项的情况下启动的
       参数并且没有标准输入的 -c 选项
       和错误都连接到终端(如确定
       通过 isatty(3)),或者以 -i 选项开头。PS1 是
       如果 bash 是交互式的,则 set 和 $- 包括 i,允许
       shell 脚本或启动文件来测试这个状态。

       以下段落描述了 bash 如何执行其
       启动文件。如果任何文件存在但不能
       读,bash 报错。波浪号在文件中展开
       名称如下所述的波浪号扩展中的
       扩展部分。

       当 bash 作为交互式登录 shell 调用时,或者作为
       带有 --login 选项的非交互式 shell,它首先
       从文件 /etc/profile 读取并执行命令,如果
       该文件存在。读取该文件后,它会查找
       ~/.bash_profile、~/.bash_login 和 ~/.profile,其中
       命令,并从第一个命令中读取并执行命令
       存在并且可读。--noprofile 选项可以
       在 shell 启动时使用以抑制此行为
       约尔。

       当登录 shell 退出时,bash 读取并执行命令
       从文件 ~/.bash_logout,如果它存在。

       当不是登录 shell 的交互式 shell 是
       启动时,bash 从 ~/.bashrc 读取并执行命令,
       如果该文件存在。这可以通过使用
       --norc 选项。--rcfile 文件选项将强制 bash
       从文件中读取和执行命令,而不是
       〜/ .bashrc。

       当 bash 以非交互方式启动时,运行 shell
       例如,它在脚本中查找变量 BASH_ENV
       环境,如果它出现在那里,它的价值就会扩大,
       并使用扩展值作为要读取的文件名
       并执行。Bash 的行为就像以下命令一样
       被处决:
              如果 [ -n "$BASH_ENV" ]; 然后 。"$BASH_ENV"; 菲
       但 PATH 变量的值不用于搜索
       为文件名。

于 2008-10-19T09:20:46.877 回答
123

在运行命令之前获取配置文件怎么样?

ssh user@host "source /etc/profile; /path/script.sh"

您可能会发现最好将其更改为~/.bash_profile,~/.bashrc或其他任何内容。

(如这里(linuxquestions.org)

于 2009-09-24T15:29:47.880 回答
106

运行远程 ssh 命令时不加载 Shell 环境。您可以编辑 ssh 环境文件:

vi ~/.ssh/environment

它的格式是:

VAR1=VALUE1
VAR2=VALUE2

另外,检查选项sshd的配置PermitUserEnvironment=yes

于 2012-04-03T12:52:24.620 回答
69

我有类似的问题,但最后我发现 ~/.bashrc 是我所需要的。

但是,在 Ubuntu 中,我不得不注释停止处理 ~/.bashrc 的行:

#If not running interactively, don't do anything
[ -z "$PS1" ] && return
于 2010-11-13T17:11:16.210 回答
4

我发现解决此问题的一个简单方法是将源 /etc/profile 添加到我试图在目标系统上运行的 script.sh 文件的顶部。在此处的系统上,这导致将 script.sh 所需的环境变量配置为好像从登录 shell 运行一样。

在先前的回复之一中,建议使用 ~/.bashr_profile 等...。我没有花太多时间在这上面,但是问题是,如果你 ssh 到目标系统上的另一个用户,而不是你登录的源系统上的 shell,在我看来,这会导致源系统用户用于~的名称。

于 2011-01-05T19:13:53.063 回答
4

只需在 ~/.bashrc 中检查非交互式 shell 的上方导出您想要的环境变量。

于 2012-02-15T06:27:13.113 回答