将数组传递给 SSH 连接

Pass arrays to SSH connections

我想将数组传递给远程计算机上的脚本。我为此使用 SSH。我尝试了以下代码,但收到一条错误消息,指出该参数不可用。

ssh -i location/to/keyfile -o StrictHostKeyChecking=no -T ubuntu@18.220.20.50 ./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b "${array_1[*]}"  -u "${array_2[*]}"

这里${array_1}${array_2}是索引数组。

如果我理解正确的话,你有两个包含数字的数组,比如:

array_1=(1 2 3)
array_2=(21 22 23)

...并希望将这些数字列表作为 space 分隔列表传递给脚本,类似于 运行 远程计算机上的这个:

./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b "1 2 3"  -u "21 22 23"

如果正确,请尝试以下命令:

ssh -i location/to/keyfile -o StrictHostKeyChecking=no -T ubuntu@18.220.20.50 ./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b "'${array_1[*]}'"  -u "'${array_2[*]}'"

解释:通过 ssh 传递的命令被解析了两次;首先由本地 shell,然后结果由远程 shell 再次 解析。在这些解析阶段的每一个中,引号(和转义)都会被应用 并被移除 。您的原始命令只有一层引号,因此本地 shell 解析、应用并删除它,因此远程 shell 看不到任何引号,因此它将每个数字视为分开的东西。

更详细:原始命令:

ssh -i location/to/keyfile -o StrictHostKeyChecking=no -T ubuntu@18.220.20.50 ./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b "${array_1[*]}"  -u "${array_2[*]}"

扩展了数组引用,给出了等同于(假设我上面列出的数组内容):

ssh -i location/to/keyfile -o StrictHostKeyChecking=no -T ubuntu@18.220.20.50 ./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b "1 2 3"  -u "21 22 23"

本地 shell 解析并删除引号,但它们具有将 1 2 321 22 23 作为单个参数传递给 ssh 程序的效果。但是 ssh 只是将它返回的命令参数列表与它们之间的 spaces 粘贴在一起,所以这就是它发送到远程 shell:

的内容
./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b 1 2 3  -u 21 22 23

...这会混淆脚本。

我的解决方案,在数组引用周围添加单引号,不会改变本地解析(单引号在双引号内,所以它们没有特殊效果);他们刚刚通过,导致这个命令被发送到远程 shell:

./script.sh -m 1G -s 0 -d 120 -w 60 -j 512M -k 512M -l 515M -b '1 2 3'  -u '21 22 23'

此处的单引号与双引号具有相同的效果(因为其中没有其他引号、转义符、美元符号或其他特殊字符),因此这应该会给出您想要的结果。

另一种解决方案与
中的答案略有不同 想法是将数组定义作为文本传递;
然后通过标准输入设备评估它们
下面的示例代码片段
你需要用你自己的数组定义脚本替换 echo 部分,
并将 source /dev/stdin 放入 script.sh

echo 'array_1[id]=3.14'|ssh  ubuntu@18.220.20.50 'source /dev/stdin; echo ${array_1[id]}'