I'm trying to understand how (ba)sh works "under the hood". I noticed one problems that bothers me. Most of parameters such as @, ? or even * can be treated as readonly variables. They can be assigned to variables that will have exactly the same "value" (e.g. STAR_VAR=$*).
@ is different, especially when used as "$@". It's more like array (let's call it SET), which can be accessed with special non-array syntax, e.g. "$@" instead of "${SET[@]}". You can learn how and when to use it, but still - is's quite confusing way of accessing "numbered" parameters (it's more like array but you're accessing with non-array syntax).
Bash was improved a lot to replace legacy constructs like `` with more "clean" syntax like $(). I wonder why this aspect was not cleaned up to make bash syntax less tricky, eg. adding to shell's or function's environment array variable (e.g. SET) with "numbered" parameters inside (with option to use legacy syntax of course)?
"$@"is a super very special POSIX (not Bash) hack that is handled super very special specially with super very special syntax as specified by the POSIX shell specification https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 .The
$(...)notation was introduced by Ksh, not by Bash.Portability. Bash keeps portability with POSIX.
"$@"is very POSIX. According to wiki, introduced in SVR3 shell (1986).Bash works "under the hood" exactly the same way it is specified to. The
"$@"is replaced by words of positional arguments, without running word splitting and filename expansion over those words and without joining those words. The source code is here https://github.com/bminor/bash/blob/f3b6bd19457e260b65d11f2712ec3da56cef463f/subst.c#L10993 and https://github.com/bminor/bash/blob/f3b6bd19457e260b65d11f2712ec3da56cef463f/subst.c#L10453 .