Bash 从stdin读取行并在其上运行命令
我正在尝试使以下命令生效Bash 从stdin读取行并在其上运行命令,bash,shell,gcloud,Bash,Shell,Gcloud,我正在尝试使以下命令生效 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 >
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命令会连接到第一个节点,而在第三个节点上运行gcloud命令根本不起任何作用
除了第三个节点外,所有节点上的peers.txt文件也奇怪地只有后两个IP
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
让它与for循环一起工作 还了解到for循环不适用于管道到:)
让它与for循环一起工作 还了解到for循环不适用于管道到:)
管道到循环中没有什么错(假设不需要在当前shell中执行循环体)。不过,对于类似的事情,您不想使用
for
循环;有关更多信息,请参阅。使用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
循环中输入的命令也从标准输入读取数据,这会在读取
之前消耗管道中的数据。在这种情况下,您可以从/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
gcloud计算实例列表--format=json--regexp.*gluster.*
jq-r'.[].networkInterfaces[].networkIP'|
而IFS=read-ri;做
gcloud compute ssh--zone$zoneubuntu@gluster-1 \
--“sudo gluster对等探测器$i>peers.txt“
完成
或者,使用进程替换从不同的文件描述符读取
while IFS= read -r i <&3; do
gcloud ...
done 3< <(gcloud compute instances .. | jq -r '...')
当IFS=read-ri时,将管道连接到循环中没有问题(假设不需要在当前shell中执行循环体)。不过,对于类似的事情,您不想使用for
循环;有关更多信息,请参阅。使用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
循环中输入的命令也从标准输入读取数据,这会在读取
之前消耗管道中的数据。在这种情况下,您可以从/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
gcloud计算实例列表--format=json--regexp.*gluster.*
jq-r'.[].networkInterfaces[].networkIP'|
而IFS=read-ri;做
gcloud compute ssh--zone$zoneubuntu@gluster-1 \
--“sudo gluster对等探测器$i>peers.txt“
完成
或者,使用进程替换从不同的文件描述符读取
while IFS= read -r i <&3; do
gcloud ...
done 3< <(gcloud compute instances .. | jq -r '...')
当IFS=read-r时,我注意到gcloud包含了jq的许多特性。下面生成相同的结果gcloud计算实例列表--format=“value(networkInterfaces.networkIP)”--filter=“name~gluster”
注意,gcloud包含了jq的许多功能。下面生成相同的结果gcloud计算实例列表--format=“value(networkInterfaces.networkIP)”--filter=“name~gluster”