Argument mixes string and array — use one or the other

"prefix$@" mashes the first array element onto prefix and leaves the rest separate. Almost never what you want.

Problem

`"$@"` expands each positional parameter as a separate quoted word — that's its whole purpose. Concatenating a literal in front (`"x$@"`) only sticks to the *first* element; the rest stay independent. The result is almost certainly a bug.

Bad

log "called with: $@"          # only first arg is attached to "called with:"

Good

log "called with: $*"          # one space-joined string
log "called with:" "$@"        # log() sees prefix, then each arg

Explanation

Use `$*` (quoted) when you want all arguments joined into one string. Use `"$@"` (quoted) when you want them preserved as separate words. Don't mix a literal with `$@`.

Related

SC2068

When It Matters

Writing "prefix $@" concatenates the prefix onto the first argument and leaves the rest as separate words, producing output that looks almost right and is wrong in a way people struggle to see. With three arguments a b c you get "prefix a", "b", "c" rather than the single string you expected. It shows up in logging wrappers, where the mangled first argument is exactly the part that carries the message.

Second Example

Note

"$*" joins with the first character of IFS (a space by default); "$@" preserves each argument as its own word. Choose based on whether you want one string or a list.

Exceptions

There is no case where the mixed form is what you want — pick "$*" for a joined string or "$@" for a list. If a specific separator is needed, set IFS locally: local IFS=,; echo "$*".

Faq

Q

When should I use "$@" instead of "$*"?

A

Whenever you are passing arguments on to another command. "$@" preserves the original word boundaries; "$*" flattens them into one argument.

Q

What happens with no arguments at all?

A

"$@" expands to nothing — zero words — while "$*" expands to a single empty string. That difference matters when the result is counted or tested.

Q

How do I join arguments with a comma?

A

Set IFS for the scope: local IFS=,; then "$*" joins with commas.