Bryce Thomas
Bryce Thomas

Reputation: 10799

Issue with copying bash array and only first element being present

I would like to declare an array, temporally change it's value while storing the old value, perform some computation and then later restore the original array value. Of this process, my original array declaration, reassigning the array, and even the temporary array copy seem to all be working. However I am running into an issue with the final restoration of the array back to its original value.

The below script demonstrates the issue. MY_ARR is the main array and SAVE_MY_ARR is the copy I am making while I modify the array temporarily before restoring it. As per the script comments, everything prints out as expected, with the exception of the original array after restoring its value. What am I doing incorrectly here?

The script:

IFS=$'\n'

MY_ARR=(one two three)
# GOOD: prints "one,two,three,"
for i in ${MY_ARR[@]}; do
    echo -n "$i,"
done
echo ""

SAVE_MY_ARR=("${MY_ARR[@]}")
MY_ARR=(foo)
# GOOD: prints "foo,"
for i in ${MY_ARR[@]}; do
    echo -n "$i,"
done
echo ""

# GOOD: prints "one;two;three"
for i in ${SAVE_MY_ARR[@]}; do
    echo -n "$i;"
done
echo ""

# BAD: prints "one," and not "one,two,three,"
MY_ARR=("${SAVE_MY_ARR}")
for i in ${MY_ARR[@]}; do
    echo -n "$i,"
done
echo ""

The output:

one,two,three,
foo,
one;two;three;
one,

Upvotes: 0

Views: 128

Answers (2)

chepner
chepner

Reputation: 531708

bash arrays are not first-class objects. In your case, you discovered that $foo does not expand to all the elements of the array foo; it is identical to ${foo[0]} and expands to only the first element of the array. The only way to copy an array is to create a new array which is initialized to the values of the first array, by expanding the first array into a sequence of its elements.

Upvotes: 0

GHugo
GHugo

Reputation: 2654

I think it's a typo mistake, here replace:

# BAD: prints "one," and not "one,two,three,"
MY_ARR=("${SAVE_MY_ARR}")

By

# BAD: prints "one," and not "one,two,three,"
MY_ARR=("${SAVE_MY_ARR[@]}")

Adding the [@] to SAVE_MY_ARR.

Upvotes: 1

Related Questions