我想捕获一些以注释中的特定模式开头的iptables规则,然后将其删除。这是我想要实现的。这是我的bash脚本
ssh -o "StrictHostKeyChecking no" root@$ip_address << EOF
echo "Now Removing your IPTables";
#storing output in input variable
input=$(iptables -nL INPUT --line-number | grep ip.* | cut -d " " -f1 | xargs)
#converting variable into an array
arr1=($input);
#loop through each element of array
echo "length:${#arr1[@]}";
for (( i="${#arr1[@]}"-1;i >=0; i-- ));
do
echo "$i:${arr1[$i]}"
iptables -D INPUT $i;
done;
EOF
问题是远程计算机上没有执行iptables命令,并且输出显示arr1的长度为0。但是我确定iptables的规则符合我的期望模式。
在终端中显示错误:
-bash: line 9: 3: command not found
在命令末尾添加2>&1
也不起作用:
input=$(iptables -nL INPUT --line-number | grep ip.* | cut -d " " -f1 | xargs 2>&1)
答案 0 :(得分:2)
TL; DR:使用<<"EOF"
代替<<EOF
。
您的此处文档将在脚本甚至发送到ssh服务器之前扩展所有变量并评估所有子shell。
考虑以下脚本:
ssh user@servername <<EOF
echo "$(hostname)"
EOF
这不会不打印servername
(您要连接的计算机的名称),而是打印您的本地主机的名称(您正在使用的计算机的名称)。
在执行ssh
之前,将执行子外壳$(hostname)
。然后将结果字符串“ echo localhostname
”传递到ssh
并在远程服务器上执行。
要解决此问题,您必须在Here-Document内转义$
或使用文字Here-Document:
ssh user@servername <<"EOF"
echo "$(hostname)"
EOF