Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash array creation: ("$@") vs ($@)

Tags:

linux

bash

shell

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.

like image 563
Roxana Avatar asked Mar 02 '14 17:03

Roxana


1 Answers

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.

like image 128
Gordon Davisson Avatar answered Oct 06 '22 20:10

Gordon Davisson