【问题标题】:Passing environment variables over ssh for remote expansion通过 ssh 传递环境变量以进行远程扩展
【发布时间】:2017-02-22 20:38:51
【问题描述】:

我正在尝试将环境变量传递给我的 shell 脚本,然后回显我传入的内容。在此示例中,$HOME 是已设置的环境变量。

./my_script.ksh $HOME

#! /usr/bin/ksh
my_var=${1}
echo "You sent: ${my_var}"

我希望我的输出为You sent: $HOME,但它正在评估它并生成You Sent: /home/blah/usr

这点是我打算做一个 SSH 命令,我需要传递 $my_var 太未评估(又名 $HOME),因为每个服务器上的 $HOME 是不同的值,并且对于我想要的 SSH 命令它使用来自服务器的值,它也是 SSH 的。所以希望只是传递它,以便在 SSH 期间它会正确评估

这是我想要发生的事情的一个例子。假设已经在 Server1 和 Server2 上设置了 $HOME,例如:

Server1 $HOME: /home/blah/usr
Server2 $HOME: /home/superblah/newusr

从 Server1 执行my_script.ksh $HOME

脚本同上,多了一行:

ssh my_user@Server2 "echo Server got: $my_var"

我目前的输出是:

You sent: /home/blah/usr
Server got: /home/blah/usr

我想要的只是生成的 ssh 命令:

Server got: /home/superblah/newusr

谢谢。

【问题讨论】:

  • 需要明确的是,your real question 涉及 SCP 而不是 SSH 是一个非常相关的区别。
  • 另外,使用 $HOME 有点误导——当 SCP 或 SSH 连接建立为 $HOME 时,它适用于依赖默认远程目录的答案,而您的实际用例需要一些东西更多参与。
  • 顺便说一句,我在这里为 ksh93 编写代码——如果您要切换到 bash,您可能希望将 foo=$(printf '%q ' ...) 替换为 printf -v foo '%q ' ...,但不会有太大变化。另一方面,如果您使用的是 ksh 的第 3 方克隆而不是真实的东西,我的第一个建议是切换 - 切换到真正的 ksh(如果您想要快速、功能强大且稳定的东西)或 bash(对于一些东西不是那么快,但积极维护——在当前的 4.x 中,即使语法不同,功能也非常接近)。
  • 顺便说一句,我是否正确地在您的历史记录中没有看到一个被接受的答案?接受答案(如果它们有效)是这里工作流程的重要组成部分——这是我们确定问题是否已得到可接受解决或仍需要更多关注的方式;此外,接受答案可为提出相关问题的人提供名义上的 (+2) 代表奖励。

标签: shell ssh


【解决方案1】:

您可以通过将变量括在单引号中来防止解析变量

./my_script.ksh '$HOME'

我试过这样:

[host1]$ echo $HOME
/home/user1
[host1]$ ssh user2@host2 echo '$HOME'
/home/user2
[host1]$

【讨论】:

  • OP 编辑​​了他们的问题,要求进行远程评估,而不仅仅是文字传输。 (我相信他们真正的问题是stackoverflow.com/questions/42400222/…,他们也稍早提出了这个问题。
  • ...当然,安全地进行远程评估——没有与eval相关的安全风险——意味着做一些工作。
【解决方案2】:

envsubst 可用于将$HOME$foo 形式的字符串替换为同名环境变量的值。因此:

#!/usr/bin/env ksh
my_var=$1
my_var_subst=$(envsubst <<<"$my_var")
echo "You sent: ${my_var}"
echo "Interpreted as: ${my_var_subst}"

...将发出:

You sent: $HOME
Interpreted as: /home/superblah/newusr

当使用./myscript '$HOME' 调用时。


请注意,在通过 SSH 传递值时需要小心,因为 SSH 会隐式运行 sh -c "$*" 并传递参数——将它们与空格连接在一起,并将单个字符串作为 shell 命令进行评估。因此,通过 ssh 运行命令可能如下所示:

ssh somehost $'./myscript \'$HOME\''

...或...

ssh somehost "./myscript \$HOME"

...或者,为了更容易,让 shell 为您完成转义工作:

remote_command=$(printf '%q ' ./myscript '$HOME')
ssh somehost "$remote_command"

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 1970-01-01
    • 2017-07-30
    • 2011-10-08
    • 2016-11-16
    • 2011-04-26
    • 1970-01-01
    • 2011-06-29
    相关资源
    最近更新 更多