6

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[@]})?

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.

  • Added more details you may want to be aware of. – llua Jun 27 '13 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.

  • 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 '13 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.