Array variable is being reassigned as a string
Assigning a plain value to a variable previously declared/used as an array overwrites it with a scalar. SC2178 flags this loss of array-ness.
Problem
Once a variable has been declared or used as an array (`declare -a arr`, or `arr=(...)`), assigning to it with plain `arr=value` (no parentheses) does not add an element — it replaces the entire array with a single-element scalar assignment to index 0, discarding every other element and effectively demoting the variable back to string-like use. ShellCheck flags this because it is very often unintentional: the author wanted to either add an item to the array or reset it to a fresh single value, but wrote the assignment in a way that quietly destroys the existing array structure.
Bad
declare -a files=(a.txt b.txt c.txt)
files="d.txt" # destroys the array, files is now just files[0]="d.txt"Good
declare -a files=(a.txt b.txt c.txt)
files=("d.txt") # replace with a new array
# or, to append:
files+=("d.txt")Explanation
Use `arr=(...)` to reassign an array wholesale and `arr+=(...)` to append elements while preserving the existing ones. If you truly intend to convert the variable into a scalar going forward, do so deliberately and make sure nothing downstream still expects array semantics.
Related
SC2124
SC2128
SC2206
When It Matters
Assigning a plain string to a name that was declared as an array replaces element zero and leaves the rest of the array in place. The variable is then half array and half scalar, and later code reading "${arr[@]}" gets a mixture of the new value and stale elements. It usually happens when a variable is reused for a different purpose halfway down a script, and the resulting bug is very hard to read back from the symptoms.
Second Example
Note
unset files before reassigning if the variable must change type — the declaration attribute survives a plain assignment.
Exceptions
None. Reusing a name for two types is a readability problem even when the mechanics happen to work; give the second use its own name.
Faq
Q
How do I clear an array completely?
A
arr=() empties it while keeping the array attribute; unset arr removes the variable and its attributes entirely.
Q
Why does ${#arr} not show the element count?
A
Without an index it gives the string length of element zero. The count is ${#arr[@]}.
Q
Does declare -a make later scalar assignment an error?
A
No, Bash allows it and treats it as an assignment to index 0 — which is precisely why the check exists.