【问题标题】:Passing a variable to a remote host in a bash script with ssh and EOF [duplicate]使用 ssh 和 EOF 在 bash 脚本中将变量传递给远程主机 [重复]
【发布时间】:2016-05-09 04:00:50
【问题描述】:

我有一个解析服务器列表的脚本,如果情况正确,我会查找一些内容并执行命令。 主服务器通过 ssh 连接到它们,执行 EOF 语句中的所有命令:

#!/bin/bash

# parsing servers
# defining one local variable $VAR

ssh -T -p 1234 root@"server-ip" "$variable" << 'EOF'
# doing some stuff...
var_result=$(mysql -hhost -uuser '-ppasswort' -Ddatabase -N -e "SELECT something FROM somewhere WHERE value=$VAR;")
EOF

如果我从 EOF 中删除单引号,我知道变量可以通过,但如果我这样做,mysql 语句将无法工作并且一切都会中断。

我知道有很多方法可以传递变量,但是用“;”表示的东西between options 对我不起作用(脚本尝试将其作为命令执行)

有什么想法吗?

【问题讨论】:

  • 举一些你想要什么和不想要什么的例子......
  • 我只想在 EOF 语句中使用本地定义的变量,但我尝试的一切都对我不起作用。如果我想在远程服务器上回显变量,我没有得到任何结果 -> 所以脚本不会发送它。
  • 将您的 mysql 语句添加到您的问题中。
  • 顺便说一句——如果这个值来自一个不受信任的来源,虽然我的答案是安全的,但它不会对 SQL 注入风险做任何事情。 (我没有在回答中引用实际的 mysql 命令,因为我不想做任何表现出不良做法的事情)。您可能会研究是否有办法通过命令行将字符串作为绑定变量传递——我曾经构建了一个可以做到这一点的 PostgreSQL 客户端,回到过去;我希望在 MySQL 中也能做到这一点。

标签: bash ssh remote-access heredoc


【解决方案1】:

使用printf %qeval-safe 形式转义内容;完成后,您可以在远程 shell 的命令行中传递它们,并通过远程脚本中的$1$2 等来检索它们:

# put contents of $VAR into $var_str in a format that a shell can interpret
printf -v var_str %q "$VAR"

#                                    v- pass the value on the shell command line
#                                    |           v- keep escaping the heredoc securely
#                                    |           |
ssh -T -p 1234 root@"$host" "bash -s $var_str" <<'EOF'

# retrieve it off the shell command line
var=$1

# ...and use it as you like thereafter.
echo "Remotely using $var"
EOF

【讨论】:

  • Charles,我一直在成功使用您的方法。但是我如何使用这种方法来传递数组而不是字符串呢?
  • @Twoez,多个数组,还是只有一个?单个数组是微不足道的; printf -v var_str '%q ' "${array[@]}",然后是array=( "$@" );对于不止一个问题,我会在另一个问题中讨论技术——请参阅stackoverflow.com/a/10953834/14122 的“bash 4.3 之前”部分
【解决方案2】:

如何使用不带引号的EOF 并使mysql 命令起作用:

#!/bin/bash

# parsing servers
# defining one local variable $VAR
VAR=something

ssh -T -p 1234 root@"server-ip" <<EOF
# doing some stuff...
var_result=\$(mysql -hhost -uuser '-ppasswort' -Ddatabase -N -e "SELECT something FROM somewhere WHERE value=$VAR;")
EOF

正如Charles Duffy 所说,这可能会产生一些安全风险。

另一种方法是将所有代码用单引号括起来:

#!/bin/bash

# parsing servers
# defining one local variable $VAR

ssh -T -p 1234 root@"server-ip" '
# doing some stuff...
var_result=$(mysql -hhost -uuser "-ppasswort" -Ddatabase -N -e "SELECT something FROM somewhere WHERE value='"$VAR"';")
'

在这种情况下,您必须小心替换变量的内容。如果你应该关心它,最好使用Charles Duffys' 方法。

【讨论】:

  • “bash
  • 我试过:export variable="dummy" 但是当我在 EOF 语句中回显时,它不会打印我的变量,只是一个空行。
  • 好的。谢谢你的时间。
  • 在当前修改的答案中,您仍在结束用于变量替换的单引号,允许将任意代码替换到远程字符串中。
  • ...另外,如果您在替换前结束单引号后没有启动双引号上下文,则替换的任何空格都将受到分词;空白环绕的球体可以扩展;等
猜你喜欢
  • 2013-03-24
  • 2015-07-05
  • 2011-10-08
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多