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
      CommentedJun 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
      CommentedJun 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.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.