3

What is wrong in this approach I can't get correct value of array length

#!/bin/bash

foo(){

    val=$@
    len=${#val[@]}
    echo "Array contains: " $val
    echo "Array length is: " $len

}

var=(1 2 3)
foo ${var[@]}

Output:

Array contains: 1 2 3
Array length is: 1
codeforester
  • 39,467
  • 16
  • 112
  • 140
Dsujan
  • 411
  • 3
  • 14
  • 1
    This was helpful for me to identify gotchas in your script above: https://askubuntu.com/questions/674333/how-to-pass-an-array-as-function-argument – DevOops Mar 26 '18 at 17:10
  • 2
    `$#` is already the length of `$@`; you don't need to create an array first. – chepner Mar 26 '18 at 17:39
  • 1
    Possible duplicate of [How to find the array length in unix shell?](https://stackoverflow.com/q/1886374/608639), [Array Length is 1 in Bash scripting](https://stackoverflow.com/q/29621652/608639), etc. – jww Mar 26 '18 at 18:34
  • Is it necessary to distinguish, whether the argument(s) are in fact an array? For example `foo 1 "a b" foobar` - shall it report an array of size 3, without any array being involved? – user unknown Mar 26 '18 at 19:45
  • 1
    The proposed duplicate only tells you things the OP obviously already knows. The proper duplicate would say "use quotes everywhere unless you can explain why not." – tripleee Mar 27 '18 at 10:33

1 Answers1

5

Change val=$@ to val=("${@}") and you should be fine.

This answer in unix.stackexchange explains why:

You're flattening the input into a single value.

You should do

list=("${@}") 

to maintain the array and the potential of whitespace in arguments.

If you miss out the " then something like ./script.sh "a b" 2 3 4 will return a length of 5 because the first argument will be split up

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • This doesn't distinguish input `foo 1 2 3` and `var=(1 2 3); foo ${var[@]}` and the len and the contains need fixing too. – user unknown Mar 26 '18 at 17:17
  • @Maroun What if I have to pass two arguments to the function the `list=("${@}") ` will merge the parameters into one and will echo as a single array. How can I get each parameter separately by this approach. – Dsujan Mar 27 '18 at 11:19