关于linux:如何在bash脚本中将局部变量传递给ssh作用域?

 2019-09-09 

How to pass local variables to ssh scope in bash script?

我正在编写bash脚本,它必须通过ssh在远程服务器上执行一些命令。 该脚本有两个主要部分:

第1部分:
使用局部变量$ A和$ B.

第2部分:
在远程服务器上执行命令,如下所示:


ssh -T user@servername << 'EOF' ... Using local variables $A and $B ... EOF

问题是在远程服务器上的ssh命令范围内,本地变量$ A和$ B不可用。 据我所知,变量$ A和$ B在ssh范围之外和之内是不一样的。

所以我的问题是如何将局部变量从bash脚本传递到ssh作用域?
还有一点需要注意,第2部分非常大,所以我不能在ssh之后使用"one liner"。

谢谢


这个问题与ssh无关,但只与bash或其他任何Posix shell中的文档有关。

bash的man页面在这里的文档段落中说:

The format of here-documents is:

<<[-]word
here-document
delimiter

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \ is ignored, and \ must be used to quote the characters \, $, and ` .

当您引用EOF时,您明确要求shell不要替换$1$2变量。

最强大的方法是不引用EOF并在此处的文档中始终引用所有其他特殊字符。

例如,如果您的here文档包含以下内容:

1
2
3
4
5
ssh -T user@servername << 'EOF'
for f in /var/log/messages*
do echo"Filename:" $f
done
EOF

你可以在EOF周围没有引号但是在$内有一个引号重写它:

1
2
3
4
5
ssh -T user@servername << EOF
for f in /var/log/messages*
do echo"Filename:" \$f
done
EOF

这样,所有未引用的变量都将被插值。

或者,如果服务器允许,您可以尝试将2个参数作为环境变量传递。

假设您要使用名称PARAM1PARAM2。服务器上的sshd_config文件应包含行AcceptEnv PARAM1 PARAM2,因为默认情况下出于安全原因,不接受任何环境变量。

然后你可以使用:

1
2
3
4
5
6
7
export PARAM1=$1
export PARAM2=$2
ssh -T -o SendEnv=PARAM1 -o SenEnv=PARAM2 user@servername  << 'EOF'
...
Using variables $PARAM1 and $PARAM2
...
EOF


可能有一种方法可以直接告诉ssh使用局部变量,但我会快速回答并提及你可以使用一个脚本来包装ssh,其代码可以远程插入变量,一旦你获得了控制权就可以访问它们。命令提示符。