如果我 ssh 到机器并运行它,我有一个运行良好的命令,但是当我尝试使用远程 ssh 命令运行它时失败,例如:
ssh user@IP <command>
在不同环境中使用两种方法比较“env”的输出。当我手动登录机器并运行 env 时,我得到的环境变量比运行时多得多:
ssh user@IP "env"
知道为什么吗?
如果我 ssh 到机器并运行它,我有一个运行良好的命令,但是当我尝试使用远程 ssh 命令运行它时失败,例如:
ssh user@IP <command>
在不同环境中使用两种方法比较“env”的输出。当我手动登录机器并运行 env 时,我得到的环境变量比运行时多得多:
ssh user@IP "env"
知道为什么吗?
有不同类型的贝壳。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 变量的值不用于搜索 为文件名。
在运行命令之前获取配置文件怎么样?
ssh user@host "source /etc/profile; /path/script.sh"
您可能会发现最好将其更改为~/.bash_profile
,~/.bashrc
或其他任何内容。
运行远程 ssh 命令时不加载 Shell 环境。您可以编辑 ssh 环境文件:
vi ~/.ssh/environment
它的格式是:
VAR1=VALUE1
VAR2=VALUE2
另外,检查选项sshd
的配置PermitUserEnvironment=yes
。
我有类似的问题,但最后我发现 ~/.bashrc 是我所需要的。
但是,在 Ubuntu 中,我不得不注释停止处理 ~/.bashrc 的行:
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
我发现解决此问题的一个简单方法是将源 /etc/profile 添加到我试图在目标系统上运行的 script.sh 文件的顶部。在此处的系统上,这导致将 script.sh 所需的环境变量配置为好像从登录 shell 运行一样。
在先前的回复之一中,建议使用 ~/.bashr_profile 等...。我没有花太多时间在这上面,但是问题是,如果你 ssh 到目标系统上的另一个用户,而不是你登录的源系统上的 shell,在我看来,这会导致源系统用户用于~的名称。
只需在 ~/.bashrc 中检查非交互式 shell 的上方导出您想要的环境变量。