Why does --text="$@" only pass the first word?

$@ expands to separate words (whereas $* expands to a single word), as explained in the bash manual. Thus, when you write

zenity --text="$@"

it expands to

zenity --text="$1" "$2" "$3"

However, shell variable assignments do not undergo word splitting. Note that field / word splitting is omitted in the list of expansions for variable assignments in the bash manual. This behavior is consistent with the POSIX spec. So, when you write

text="$@"

the variable text gets all of the positional parameters as a single word, equivalent to if you had written text="$*". Indeed, this is the reason double quotes are often unnecessary in variable assignments. Both

text=$@

and

text=$*

are perfectly safe.

So,

text=$@
zenity --option="$text"

expands "$text" to a single word, which is why this works. Note that the --option="$@" is just a normal argument to the command zenity, and not a shell variable assignment, which is why word splitting takes place here but not in text=$@.


$@ get expanded each parameter in separate word, becoming

zenity --entry --text="arg1" "arg2" "arg3" # syntactically wrong for zenity

Use $* instead to expand it in a single word

zenity --entry --text="$*"

which will become

zenity --entry --text="arg1 arg2 arg3" # syntactically correct for zenity