1

When I try to pass an array as parameter and add a value to it, it end's up as being empty at the end.

How would I add value to passed array? I would make the array global, but I will be passing different arrays, so it must be passed to this function as parameter.

#!/bin/bash

base='/home'

declare -a files_new
declare index

arrayit() {
    #$1 = path
    #$2 = array

    dir=($1/*)
    arr=$2

    for directory in "${dir[@]}"
    do
        if [[ -d $directory ]]
        then
            arrayit $directory $arr
        else
            arr[$index++]=$directory
        fi
    done
}

index=0
arrayit $base $files_new

for file in "${files_new[@]}"
do
    echo "File: $file"
done
6
  • I assume. But I'm not sure if I'm declaring it correctly inside function with $2. Commented Feb 6, 2016 at 19:18
  • arr is not an array; you are passing the first element ($files_new is equivalent to ${files_new[0]}) as a regular string, and assigning that to arr. Commented Feb 6, 2016 at 19:38
  • Thanks chepner; Would passing ${files_new[@]} be considered as passing entire array? Commented Feb 6, 2016 at 19:42
  • It would pass the contents of the array, not the array itself (meaning you wouldn't be able to modify the array from within the function). Commented Feb 6, 2016 at 19:48
  • 1
    If you are using bash 4, you can throw out arrayit altogether and just set files_new=( "$base"/**/*/ ) to get a recursive list of directory names. (With shopt -s globstar to enable use of **.) Commented Feb 6, 2016 at 19:58

1 Answer 1

1

Passing around arrays in bash is a real PITA. I've found this is the most reliable method

$ ary=(foo bar baz)
$ fn() { local tmp="${1}[@]"; local copy=("${!tmp}"); declare -p copy; }
$ fn ary
declare -a copy='([0]="foo" [1]="bar" [2]="baz")'

That gives you a copy in the function. Changes made in the function will not appear in the parent scope.

However, bash version 4.3 has "name references"

$ fn() { 
    local -n myary=$1       # note: -n -- see "help declare"
    declare -p myary
    for key in "${!myary[@]}"; do printf "%s\t%s\n" "$key" "${myary[$key]}"; done
    myary[42]="new value"
}
$ fn ary
declare -n myary="ary"
0   foo
1   bar
2   baz
$ declare -p ary
declare -a ary='([0]="foo" [1]="bar" [2]="baz" [42]="new value")'

Note the new value in the parent scope! Hooray!

Sign up to request clarification or add additional context in comments.

1 Comment

Note that in both cases, I'm passing the name of the array to the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.