使用 ssh 和 EOF 在 bash 脚本中将变量传递给远程主机

Passing a variable to a remote host in a bash script with ssh and EOF

我有一个脚本可以解析服务器列表,查找一些内容并在情况正确时执行命令。 主服务器通过 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 语句将不起作用,一切都会中断。

我知道有一些方法可以传递变量,但是带有“;”的东西选项之间对我不起作用(脚本试图将其作为命令执行)

有什么想法吗?

如何使用不带引号的 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"';")
'

在这种情况下,您必须小心替换变量的内容。如果您担心它,最好使用 方法。

使用 printf %qeval 安全形式转义内容;这样做之后,您可以在远程 shell 的命令行上传递它们,并在远程脚本中通过 </code>、<code> 等检索它们:

# 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=

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