在 ssh 中传递变量

use*_*034 7 ssh shell-script here-document

我正在尝试将变量传递给 ssh 远程但不起作用。我的代码是:

#!/bin/bash
set -x
conexion="user@xx.yy.zz.pp"
parameter="$1"
ssh -T $conexion <<'ENDSSH' 
clear
echo "$parameter"
ENDSSH
Run Code Online (Sandbox Code Playgroud)

我执行:

./script.sh try
Run Code Online (Sandbox Code Playgroud)

它说我:

parameter: Undefined variable.
Run Code Online (Sandbox Code Playgroud)

有什么帮助吗?

Sté*_*las 9

传递变量(环境变量)ssh是可能的,但通常受到限制。

您需要告诉客户发送它们。例如使用 OpenSSH,它是:

ssh -o SendEnv=parameter host cmd...
Run Code Online (Sandbox Code Playgroud)

但是您还需要服务器接受它(AcceptEnvOpenSSH 的配置指令)。接受任何变量都会带来很大的安全风险,因此通常默认情况下不会这样做,尽管某些 ssh 部署允许某些命名空间下的某些变量(例如LC_*在某些 OpenSSH 部署中)。

您还需要在调用之前导出变量ssh,例如:

LC_parameter="$parameter" ssh -o SendEnv=LC_parameter host csh << 'END'
echo $LC_parameter:q
END
Run Code Online (Sandbox Code Playgroud)

上面,我们将$parameter bashshell 变量的内容作为LC_parameter环境变量传递给ssh. ssh将其发送给sshd,如果它接受它,则将其作为环境变量传递给用户的登录外壳,然后将其传递给该csh命令(然后可以扩展它)。

但正如前面提到的,除非host机器管理员在配置中添加了一个AcceptEnv LC_parameterAcceptEnv LC_*(有时默认这样做),否则这将不起作用sshd

Undefined variable您示例中的错误消息表明远程用户的登录 shell 是cshtcsh。最好显式调用 shell 以避免意外(ssh host csh也意味着不需要 tty,因此您不需要-T)。请注意$LC_parameter:q语法,这是csh逐字传递变量内容的方式,"$LC_parameter"如果变量包含换行符,则语法不起作用。

如果使用LC_*变量不是一种选择,那么您也可以让客户端shell(bash在您的情况下)扩展变量。一种天真的方法是

ssh host csh << END
echo "$variable"
END
Run Code Online (Sandbox Code Playgroud)

但这会很危险,因为变量的内容会被远程 shell 解释。如果$variable包含`reboot`"; reboot; : "例如,那将产生不良后果。

因此,您首先需要确保在远程 shell 的语法中正确引用了该变量。在这里,我将避免csh那里很难做得可靠和使用sh/ bash/ksh来代替。

使用辅助函数进行 sh 引用:

shquote() {
  awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
       printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}
Run Code Online (Sandbox Code Playgroud)

并调用ssh为:

ssh host sh << END
parameter=$(shquote "$parameter")
echo "\$parameter"
END
Run Code Online (Sandbox Code Playgroud)

看看我们如何转义第三个,$以便扩展$parameter由远程 shell 完成,而不是本地 shell。


ddn*_*mad 2

ENDSSH删除第四行的引号应该会有所帮助。

\n\n

礼貌:@Archemar 对问题的评论。

\n\n

警告正如 @St\xc3\xa9phaneChazelas 在对此答案的评论中所述,此解决方案将导致$parameter此处文档中的变量被本地 shell 扩展,这意味着变量的内容将被解释为 shell 代码通过远程 shell,这意味着它引入了命令注入漏洞。所以一般情况下不鼓励这样做。

\n

  • 这将导致此处文档中的“$parameter”变量被本地 shell 扩展,这意味着该变量的内容将被远程 shell 解释为 shell 代码,这意味着它引入了命令注入漏洞,例如,如果`$parameter` 的值并不完全在您的控制之下,并且您还没有对其进行清理。 (2认同)