I am running a script with: ./some_script arg1 arg2 "multiple words arg3" arg4
. I want to explode arguments ($@
) into an array. This snippet works just for arguments without spaces:
arr=($@)
If I want to store the correct arguments into array I must use:
arr=("$@")
Why should I enclose $@
in quotes?
I think this has something to do with parameter expansion and special parameters, but I don't think I got it well.
In the shell, whenever a variable (including special parameters like $@
) in referenced without double-quotes, the value goes through word splitting and wildcard expansion after it's expanded. For example:
$ var="FOO * BAR"
$ printf "%s\n" "$var"
FOO * BAR
$ printf "%s\n" $var
FOO
Desktop
Documents
Downloads
Library
Movies
Music
Pictures
Public
BAR
In the second case, the variable value "FOO * BAR" got split into separate words ("FOO", "*", and "BAR"), and then the "*" was expanded into a list of matching files. This is why you almost always want to put variable references in double-quotes.
The same thing applies to $@
-- if it's not in double-quotes, it's expanded into the list of parameters and then each one of them is subjected to that same word splitting and wildcard expansion that $var
went through above. If it's in double-quotes, the parameter values are left unmolested.
BTW, there is another way to get the parameters: $*
. This differs from $@
in that it sticks all of the parameter values together with spaces between them (while $@
maintains each parameter as a separate word). In double-quotes, "$*"
gives a single word consisting of all parameters. Without double-quotes, $*
sticks all the parameters together, then re-splits them (maybe at the same places, maybe not), and does wildcard expansion. Probably not what you wanted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With