I'm writing a script to collect some various network statistics. What I'm trying to do is to produce some delta data from the netstat -i command.
I'm collecting the needed data with the following bash code:
declare -a array
n=0
netstat -i | tail -n +3 | while read LINE; do
echo "Setting array[$n] to $LINE"
array[$n]=$LINE
echo "array now have ${#array[@]} entries"
let n=$n+1
done
echo "array now have ${#array[@]} entries"
output from this command is:
Setting array[0] to eth0 1500 0 4946794 0 0 0 2522971 0 0 0 BMRU
array now have 1 entries
Setting array[1] to lo 16436 0 25059 0 0 0 25059 0 0 0 LRU
array now have 2 entries
Setting array[2] to vmnet1 1500 0 6 0 0 0 1126 0 0 0 BMRU
array now have 3 entries
Setting array[3] to vmnet8 1500 0 955 0 0 0 1054 0 0 0 BMRU
array now have 4 entries
Setting array[4] to wlan0 1500 0 613879 0 0 0 351194 0 0 0 BMU
array now have 5 entries
array now have 0 entries
As you can see, the array actually disappear after the while loop, and I do not understand why.
Any time you use a pipe you create an implicit subshell. When that subshell terminates, so do its variables. A quick fix for this is to not pipe stuff to read
. You can accomplish the above using process substitution:
while read LINE; do
echo "Setting array[$n] to $LINE"
array[$n]=$LINE
echo "array now have ${#array[@]} entries"
let n=$n+1
done < <(netstat -i | tail -n +3)
A more POSIX compliant approach (read: more portable, less bashist) is to make everything happen in the subshell:
netstat -i | tail -n +3 | {
declare -a array
n=0
while read LINE; do
echo "Setting array[$n] to $LINE"
array[$n]=$LINE
echo "array now have ${#array[@]} entries"
let n=$n+1
done
echo "array now have ${#array[@]} entries"
}
You can read the fine points of this (and more) at Greg Wooledge's wiki.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With