8

As far as I can tell both ${#array[@]} and ${#array} evaluate to the number of elements in $array. Is there any reason for preferring the longer form (${#array[@]})?

3 Answers 3

10

In zsh, personal preference. In other shells $array may only expand to the first element, thus ${#array} would output the length of the first element.

So, if you want to be little more portable between shells specifying the [@] would work.

In zsh, $array expands in the same way $array[*] would, which differs depending on if they appear within quotes or not. Should they appear within double quotes "$array" would expand and be delimited by the first character of IFS which by default is space

zsh% touch {1..10}; a=(*)
zsh% printf '<%s> ' $a
<1> <10> <2> <3> <4> <5> <6> <7> <8> <9>     
zsh% printf '<%s> ' "$a"
<1 10 2 3 4 5 6 7 8 9> 
zsh% IFS=:
zsh% print "$a"
1:10:2:3:4:5:6:7:8:9
zsh% print "$a[@]"
1 10 2 3 4 5 6 7 8 9
zsh% IFS=$' \t\n'
zsh% rm "$a"
rm: cannot remove ‘1 10 2 3 4 5 6 7 8 9’: No such file or directory

Changing IFS is rarely needed which prompted my original "Personal preferences" response. But just to clarify there is a few differences between the two when used without the # flag, they are is just very subtle.

I prefer $array[@] also since it's behavior doesn't change depending on whether or not it appears within quotes. That and internal whitespace that an element may have is preserved.

1
  • Added more details you may want to be aware of.
    – llua
    Jun 27, 2013 at 12:57
4

As with anything, the more readable and understandable your code the easier it is for others (or future you) to maintain. When you have a choice and one of them is ambiguous, choose the other.

Additionally, if you want portability in your shell scripts, the latter is the only one that works properly in bash.

1
  • Well, that's what I saw yesterday but I didn't keep my notes and I can't reproduce it so there was something wrong with my example. I've removed that portion of my answer. But the question is about ${#array[@]}, not ${#array[0]}. Even with your example, if ${#array} and ${#array[@]} were the same you would get 5 5 on line 4, not 3 5 since the expectation is both forms count the elements of the array. In zsh they are equivalent, in bash they are not.
    – bahamat
    Jun 28, 2013 at 5:11
4

In most shells that support arrays (I've tested it in bash, ksh93 and pdksh), ${#array} will give the length of ${array[0]}, and ${#array[@]} will give the number of elements in the array. This is logical: "${array}" returns element 0 of the array and "${#array}" returns its length.

You must log in to answer this question.

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