-3

I was looking at how Gentoo's ebuilds are made and I found the following code:

_VIM_PLUGIN_ALLOWED_DIRS=(
    after autoload colors compiler doc ftdetect ftplugin indent keymap
    macros plugin spell syntax
)

local d
for d in "${_VIM_PLUGIN_ALLOWED_DIRS[@]}" "${@}"; do
                [[ -d "${d}" ]] || continue
                doins -r "${d}"
            done 

As far as I am aware, _VIM_PLUGIN_ALLOWED_DIRS is a list. d is a local variable.
The thing I don't understand is the [@] in _VIM_PLUGIN_ALLOWED_DIRS[@]. Normally I would omit the [@], and just make d iterate over _VIM_PLUGIN_ALLOWED_DIRS's values.

What is it doing? What's its purpose?

I have never seen [@], nor do I know what the ${@} does afterwards

PS: doins is an external function defined elsewhere

Thanks in advance

4
  • 1
    From Arrays (Bash Reference Manual): "Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with the shell’s filename expansion operators. If the subscript is ‘@’ or ‘*’, the word expands to all members of the array name." Commented May 14, 2023 at 0:00
  • And ${@} ${*} or equivalently $@ $* similarly access the positional parameters like an array (but these are portable to any Bournish or POSIX shell, while only ksh/bash/zsh have named arrays). Commented May 14, 2023 at 0:30
  • 1
    "just make "d" iterate over "_VIM_PLUGIN_ALLOWED_DIRS"'s values" How do you manage this magic?
    – muru
    Commented May 14, 2023 at 3:32
  • Regarding As far as I am aware, _VIM_PLUGIN_ALLOWED_DIRS is a list. - there are no lists in bash, it's an array.
    – Ed Morton
    Commented May 14, 2023 at 23:24

1 Answer 1

5

Normally I would omit the [@], and just make d iterate over _VIM_PLUGIN_ALLOWED_DIRS's values.

In ksh-style arrays that Bash also has, referencing the array without an index would only give the element at index 0. This is different from zsh, where referencing an array with an index would give all (non-empty) elements.

The special index @ is used to get all elements of the arrays as distinct fields. $@ similarly expands to all the positional parameters (arguments to the script or function).

E.g.

arr=(foo "bar doo")
printf "<%s> " "$arr"; echo       # '<foo>'
printf "<%s> " "${arr[@]}"; echo  # '<foo> <bar doo>'

Note that in both cases you should quote "${arr[@]}" and "$@" to avoid word splitting and globbing from inevitably messing up the values.

See:

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .