'bash script: Execute the same command on a list of output?

I create a bash script where I am executing this K8S command line:

kubectl get nodes -o yaml | grep -- "- address:"

The output looks like this:

- address: 10.200.116.180
- address: node-10-200-116-180
- address: 10.200.116.181
- address: node-10-200-116-181
- address: 10.200.116.182

I would like to loop the output list and make some test on every address ip for example: ping 10.200.116.182.



Solution 1:[1]

By replacing grep with sed you can directly get the IP list; and for storing those IPs in a bash array, you can use mapfile -t with a process substitution:

mapfile -t ips < <( 
    kubectl get nodes -o yaml |
    sed -nE 's/^[[:space:]]*- address: ([0-9.]+)$/\1/p'
)

Now you just have to loop through the array with a for loop:

for ip in "${ips[@]}"
do
    ping -c 1 "$ip"
done

Solution 2:[2]

You can pipe the output to xargs and execute the command you wish.

Before you do that you should clean up the output. in your example pipe your output to :

sed -e 's/^[[:space:]]*- address: \([^[:space:]]*\)[[:space:]]*$/\1/g'

you should end up with :

kubectl get nodes -o yaml | grep -- "- address:" | sed -e 's/^[[:space:]]*- address: \([^[:space:]]*\)[[:space:]]*$/\1/g'

Output should be only the addresses, like:

10.200.116.180
node-10-200-116-180
10.200.116.181
node-10-200-116-181
10.200.116.182

Now it is time to use the cleaned output to execute the ping. To pass the addresses to ping we will use xargs. To do that we are going to pipe the cleaned output to:

xargs -I {IP} ping -c 1 -w 5 {IP}

Final command :

kubectl get nodes -o yaml | grep -- "- address:" | sed -e 's/^[[:space:]]*- address: \([^[:space:]]*\)[[:space:]]*$/\1/g' | xargs -I {IP} ping -c 1 -w 5 {IP}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Rafael Kalachev