我正在编写一个脚本,以便将本地值与远程值匹配。截至目前,我的代码功能正常,如下所示:
#!bin/bash
MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
for VALUE in "${MY_ARRAY[@]}"
do
if [[ $VALUE =~ ^v ]] ; then
echo "$VALUE : $(ssh admin@machine matching_function $VALUE)" >> output.file
else
echo "$VALUE : this is a wrong value" >> output.file
fi
done
唯一的问题是,对于循环的每次迭代,它都会创建并关闭一个新的ssh连接。由于我的原始数据集很大,执行需要很长时间。
我一直在寻找一种优化方法,并阅读有关使用ssh admin@machine <<EOF
将多行命令传递给ssh并调整我的代码的信息:
MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
ssh admin@machine << EOF
for VALUE in "${MY_ARRAY[@]}"
do
if [[ $VALUE =~ ^v ]] ; then
echo "$VALUE : $(matching_function $VALUE)" >> output.file
else
echo "$VALUE : this is a wrong value" >> output.file
fi
done
EOF
然而,它不起作用,我得到了几个错误:
Pseudo-terminal will not be allocated because stdin is not a terminal.
。我怀疑这部分是由于我的远程shell受到限制,并且它与echo
冲突。
$ MY_ARRAY似乎未在远程机器上取消分配:
-rbash: line 5: conditional binary operator expected
-rbash: line 5: syntax error near unexpected token '^v'
-rbash: line 5: ' if [[ =~ ^v ]] ; then'
我也不确定bash如何区分$VALUE
(应该从我的本地计算机解释)和matching_function
(应该从远程计算机解释)
答案 0 :(得分:3)
man ssh
:
如果指定了
command
,则会在远程主机而不是登录shell上执行。
人们可能会告诉你,你可以通过使用不同数量的-t
来强制分配一个伪tty,它可以正常工作,但是会带来运行登录shell的副作用,因此最好只做< / p>
ssh admin@machine bash <<EOF
...
#some instructions
...
EOF
而是强制不执行登录shell。
答案 1 :(得分:3)
即使已经有一段时间了,我也会用我用于解决问题的解决方案回答我的问题。
在使用heredocs和SSH的组合挣扎之后,我想出了一个部分解决方案:
MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
ssh admin@machine -T << EOF >output.file
for VALUE in "${MY_ARRAY[@]}"
do
if [[ \$VALUE =~ ^v ]] ; then
echo "\$VALUE : \$(matching_function \$VALUE)"
else
echo "\$VALUE : this is a wrong value"
fi
done
EOF
我在局部变量之前使用$
,在远程变量之前使用\$
。这是由于heredoc行为,因为bash
在执行heredoc的内容之前解释了$
之前的每个变量。
>output.file
允许我捕获ssh命令的输出并进行一些后处理。但是,我从未发现如何从<<EOF ... EOF
中分配变量,但我想这更像是一个heredoc问题。
我现在接受我的回答,但是如果有人能澄清为什么/如果不可能将heredoc中的变量分配到外部,我会很高兴。