When you use the * expansion (specifically inside double quotes: "${NAMES[*]}"), Bash merges all array elements into a single string.
The IFS (Internal Field Separator) variable determines which character is used to join those elements together. By default, IFS contains a space, a tab, and a newline. Bash uses the first character of IFS as the separator.
How it works in practice
Let's look at an example in the terminal:
# Define an array
NAMES=("John" "Eric" "Jessica")
# Scenario 1: Default IFS (Space)
echo "${NAMES[*]}"
# Output: John Eric Jessica
# Scenario 2: Change IFS to a comma
IFS=","
echo "${NAMES[*]}"
# Output: John,Eric,Jessica
# Scenario 3: Change IFS to a colon
IFS=":"
echo "${NAMES[*]}"
# Output: John:Eric:Jessica
Why this is useful
This is a "secret weapon" for quickly generating CSV (Comma Separated Values) or paths without writing a loop. If you have an array and you need to turn it into a comma-separated list for a report or a command, you just temporarily change IFS.
The "Clean" Way to use it
If you change IFS in a script, it affects everything else in that script too (which can cause bugs!). It is best practice to save the old IFS and restore it:
OLD_IFS=$IFS # Save the original
IFS="|" # Set your custom separator
MY_STRING="${NAMES[*]}"
IFS=$OLD_IFS # Restore the original
Contrast with @
The IFS variable does not affect "${NAMES[@]}".
The @ expansion always keeps elements separate, regardless of what IFS is set to. This is why @ is considered "safe" and * is considered "special purpose."
In summary: IFS acts as the "glue" character when you tell Bash to "squash" an array into a single string using *.