Arrays concatenate in [[ ]] — use a loop
Comparing an array against a string in `[[ ]]` joins it with the first IFS char. Almost always a bug.
Problem
`[[ "$arr" == "value" ]]` doesn't compare the array — it concatenates the elements with the first character of IFS (usually a space) and compares the joined string. The "absent element" case looks identical to "matches", and adding elements silently changes behavior.
Bad
langs=(en de fr)
if [[ "${langs[@]}" == "fr" ]]; then ... # checks "en de fr" == "fr"Good
# Membership test with a loop:
for l in "${langs[@]}"; do
[[ "$l" == "fr" ]] && found=1
done
# Or with a regex over the joined form:
if [[ " ${langs[*]} " == *" fr "* ]]; then ...
fiExplanation
The padded-space pattern (`" ${arr[*]} "` matched against `*" item "*`) is a common idiom for "contains" without a loop. The loop version is clearer when the test grows complex.
When It Matters
Comparing "${arr[@]}" against a pattern inside [[ ]] does not test each element: the array is flattened into one string first, so the match succeeds if the pattern appears anywhere in the concatenation. A membership test written this way returns true for a value that spans two elements, which is a silent authorisation bug in permission checks. The surprise is that it works in casual testing — single-word elements usually produce the answer you expected.
Second Example
Note
For anything security-relevant, the associative-array set is both the fastest and the hardest to get subtly wrong.
Exceptions
Joining an array into a string is fine when you want the string — building a display line or a command argument. The warning is about using that joined form as if it tested individual elements.
Faq
Q
Why is the padded-space idiom risky?
A
It works only if no element contains a space. One multi-word element and the boundaries you relied on disappear.
Q
Is there a built-in membership operator?
A
No. Bash has no "in" test for indexed arrays; a loop or an associative array is the idiomatic substitute.
Q
How do I test membership case-insensitively?
A
Lowercase both sides with ${var,,} before comparing, or enable shopt -s nocasematch around the [[ ]] test.