Why isn't passed quoted $@ a single argument?
f2()
{
echo "f2: $1"
}
f1()
{
local x=("$@")
f2 "${x[@]}"
}
f1 x y
Invocation:
$ bash t537.sh
f2: x
Here I expect that x y is printed because ${x[@]} is passed to f2 in quoted form.
Why passing quoted ${x[@]} passes "x" "y" rather than passing "x y"?
P.S. It seems that "$*" may be the solution here. However, I'm trying to understand why "${x[@]}" does not work here.
"$@"is a special magical thingy, which makes an exception to the general rule. And for very good reasons. (the same applies to"${array[@]}"by extension) – ilkkachu Jan 23 '24 at 13:50"$@"is very much more often the right thing to do, as it keeps together arguments that contains separators (spaces, tabs). for exemple if you have 3 files:file1file2 with spacesfile3and write a script that asks the filenames as arguments, the 2nd should be entered with quotes"file2 with spaces"and these should stay together. The"$@"would allow you to do that, whereas"$*"or$*or$@would not. Other use case : https://mywiki.wooledge.org/BashPitfalls#for_arg_in_.24.2A – Olivier Dulac Jan 23 '24 at 15:01x=$@orx="$@", you'd get the args (positional parameters) joined to a single string. But the details vary between the shells, so better use$*there if joining them is what you want. – ilkkachu Jan 23 '24 at 15:34("$@")I convert command line arguments into an array, 2) I've fixed my code viaecho "f2: $@". – pmor Jan 24 '24 at 09:52echojoins its args with spaces. But that's a feature of echo, and e.g. printf would be different there. if you have the argsfooandbar, thenecho "f2: $@"will run echo with the two argsf2: fooandbar. Whileecho "f2: $*"would pass just the single argf2: foo bar(assuming the defaultIFS) – ilkkachu Jan 24 '24 at 10:22printf "f2: %s\n" "$@"andprintf "f2: %s\n" "$*"produce very different results. – Stephen Kitt Jan 24 '24 at 10:33