Array disappear in bash script

arrays, bash

Solution

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.

Problem

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.

Original source