So in a script I have a variable that changes each time the script is run. The variable is IP_PING. It is basically a list of if address seperated by commas.
I want the script to take each ip addess in the csv variable and ping it. The example below works fine if I only have one ip address in the variable.
IP_PING="192.168.1.1" echo "$IP_PING" | while read -r -d, ip1 do ping -c 4 "$ip1" >/dev/null if [ $? -ne 0 ]; then echo "Ping fail" else echo "Ping success" fi done
But if I change the IP_Ping variable to = “192.168.1.1,192.168.100.1” The script only reads the first value 192.168.1.1. Is “while read” the wrong command to use for this. It is reading each value as a seperate column. I want all the values in a single column and then do the while on each value. If that makes sense.
Advertisement
Answer
"192.168.1.1,192.168.100.1"
Here is your issue. The problem is that when the while loop is reading, after the first iteration there is no more commas so it hits the end and quits. "192.168.1.1,192.168.100.1,"
should show the way you are intending.
As other’s have suggested in the comments, I would go with a for loop myself, but to with closet to how you were trying to implement it, this would work for you:
IP_PING="192.168.1.1,192.168.1.2,192.168.1.3" while read -r ip1 ; do ping -c 4 "$ip1" >/dev/null if [ $? -ne 0 ]; then echo "Ping fail" else echo "Ping success" fi done < <(echo $IP_PING |tr ',' 'n')
< <(echo $IP_PING |tr ',' 'n')
is process substitution. To put it simply it will “pipe” the output into the while loop. The difference from a normal pipe being that it creates one less process; the actual pipe creates a process itself.
Using process substitution will also keep the while loop in the current environment as well. (vs a while loop usually takes a ‘snapshot’ of the env and uses that during the loop, then it disappears when the loop ends) Meaning, with process substitution, that processes in the while loop will be able to see changes in env variables of the parent while it is looping, AND variables assigned within the loop will also still be available in the parent after it ends.