我正在尝试使用以下命令
gcloud compute instances list --format=json --regexp .*gluster.* | jq '.[].networkInterfaces[].networkIP' | tr -d '\"' | while read i; do gcloud compute ssh --zone $ZONE ubuntu@gluster-1 -- "sudo gluster peer probe $i && cat >> peers.txt"; done
基本上gcloud命令给出:
gcloud compute instances list --format=json --regexp .*gluster.* | jq '.[].networkInterfaces[].networkIP' | tr -d '\"'
10.128.0.2
10.128.0.3
10.128.0.4
但是只运行上面的命令似乎只能在主机的第一个ip上运行,给出警告
peer probe: success. Probe on localhost not needed
其他节点都没有连接。
注意: 奇怪地在第二个节点上运行gcloud命令连接到第一个节点,在第三个节点上运行根本没有做任何事情
除了第三个节点之外的所有节点上的peers.txt文件再次奇怪地只有后两个节点
ubuntu@gluster-1:~$ cat peers.txt
10.128.0.3
10.128.0.4
对循环中的值运行echo给出
gcloud compute instances list --format=json --regexp .*gluster.* | jq '.[].networkInterfaces[].networkIP' | tr -d '\"' | while read i; do echo ip: $i; done
ip: 10.128.0.2
ip: 10.128.0.3
ip: 10.128.0.4
答案 0 :(得分:3)
管道进入循环没有任何问题(假设您不需要在当前shell中执行循环体)。但是,您不希望使用for
循环来执行此类操作;有关详细信息,请参阅Bash FAQ 001。使用while
循环。
gcloud compute instances list --format=json --regexp .*gluster.* |
jq -r '.[].networkInterfaces[].networkIP' |
while IFS= read -r ipaddr; do
echo "$ipaddr"
done
(请注意,对-r
使用jq
选项,无需将输出通过管道传输到tr
以删除双引号。)
您可能会遇到的问题是您在while
循环中放置的命令从标准输入读取,该标准输入在read
可以读取之前消耗来自管道的数据它。在这种情况下,您可以从/dev/null
重定向标准输入:
gcloud compute instances list --format=json --regexp .*gluster.* |
jq -r '.[].networkInterfaces[].networkIP' |
while IFS= read -r i; do
gcloud compute ssh --zone $ZONE ubuntu@gluster-1 \
-- "sudo gluster peer probe $i < /dev/null &&
cat >> peers.txt"
done
或者,使用进程替换来从不同的文件描述符中读取。
while IFS= read -r i <&3; do
gcloud ...
done 3< <(gcloud compute instances .. | jq -r '...')
答案 1 :(得分:0)
使用for循环。
还了解到for循环不用于管道:)
for item in $(gcloud compute instances list --format=json --regexp .*gluster.* | jq '.[].networkInterfaces[].networkIP' | tr -d '\"'); do gcloud compute ssh --zone $ZONE ubuntu@gluster-1 -- "sudo gluster peer probe $item && echo $item >> peers.txt"; done