这是我的脚本,其中使用heredoc
在远程计算机中使用本地变量。但是heredoc
下的循环仅采用第一个变量值。循环在heredoc
内可以正常运行,但是具有相同的值。
#!/bin/bash
prod_web=($(cat /tmp/webip.txt));
new_prod_app_private_ip=($(cat /tmp/ip.txt));
no_n=($(cat /tmp/serial.txt));
ssh -t -o StrictHostKeyChecking=no ubuntu@${prod_web[0]} -p 2345 -v << EOF
set -xv
for (( x = 0; x < '${#no_n[@]}'; x++ ))
do
sudo su
echo '${no_n[x]}'
echo '${new_prod_app_private_ip[x]}'
curl -fIkSs https://'${new_prod_app_private_ip[x]}':9002 | head -n 1
done
EOF
因此,我的ip.txt文件包含以下值:
10.0.1.0
10.0.2.0
10.0.3.0
我的serial.txt文件:
9
10
11
因此,我的循环仅对远程计算机中的第一个IP(在/tmp/ip.txt
中存在)运行3次。我想为所有三个IP运行它。我的远程IP位于文件/tmp/webip.txt
中。
长时间卡住,不胜感激。我还有其他解决方案吗?
答案 0 :(得分:1)
有2个环境。在本地计算机和远程计算机上。您需要考虑如何在这些机器之间传输数据/变量/状态/对象/句柄。
如果您在本地计算机(例如prod_web=($(cat /tmp/webip.txt));
)上进行了设置,然后仅将SSH切换到远程主机(例如ssh user@host 'echo "${prod_web[@]}"'
),则该变量将不可见/不会导出到远程计算机。您可以:
ssh .... "$(for ...; do; echo curl ...; done)"
我会选择第二种方法,因为我喜欢使用管道传递所有内容,而且不希望在我之后进行清理-如果出现错误,则删除临时文件可能会很混乱。
我的脚本可能看起来像这样:
#!/bin/bash
set -euo pipefail
read -r host _ <webip.txt
paste serial.txt ip.txt | ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" '#!/bin/bash
set -euo pipefail
while read -r no_n ip; do
for ((i = 0; i < no_n; ++i)); do
printf "%s\n" "$no_n"
printf "%s\n" "$ip"
curl -fIkSs https://"$ip":9002 | head -n 1
done
done
'
由于远程脚本将变得更大且对qouting的友好程度降低,因此我将其保存到另一个remote_scripts.sh
中并执行ssh ... -m remote_scripts.sh
。
我不了解您要如何处理该sudo su
,而该no_n
并没有满足您的要求。
如果#!/bin/bash
set -euo pipefail
read -r host _ <webip.txt
paste serial.txt ip.txt | ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" 'xargs -n2 -- sh -c "seq 0 \"\$1\" | xargs -n1 -- sh -c \"curl -fIkSs https://\\\"\\\$1\\\":9002 | head -n 1\" -- \"\$2\"" --'
幻数是执行该curl的次数,并且您有xargs并且您并不真正在意错误,那么您可以做一个幻数并混淆oneliner:
# semi-readable script, not as fast and no xargs
ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" "$(paste serial.txt ip.txt | while read -r serial ip; do
seq 0 "$serial" | while read -r _; do
echo "curl -fIkSs \"https://$ip:9002\" | head -n 1"
done
准备运行所有命令实际上可能更具可读性,并且可以节省一些烦人的qouting来解决。但这实际上取决于serial.txt和ip.txt的大小以及要在远程计算机上执行的命令的大小,因为您希望最大程度地减少计算机之间传输的字节数。
这里要运行的命令是在本地计算机上构造的(即,“ $(...)”传递给ssh)并在远程计算机上执行:
$ cat <<EOF
> echo 1
> EOF
echo 1
完成)”
HERE-doc不会扩展shell命令,因此:
$( ... )
但是您可以使用命令替换$ cat <<EOF
> $(echo 1)
> EOF
1
:
{{1}}