2

I am trying to pass a array into a function and whatever changes made to the array is reflected outside the function

function update_array()
{   
    ${1[0]}="abc" # trying to change zero-index array to "abc" , 
                  #  bad substitution error


}

foo=(foo bar)

update_array foo[@]

for i in ${foo[@]}
    do
       echo "$i" # currently changes are not reflected outside the function

    done

My questions are

1) How do i access the index array eg: zero index array , in the function , what is the syntax for it

2) How do i make changes to this index array so that the changes are reflected outsite the function also

3 Answers 3

3

Several problems, in logical order of fixing:

  • Style (pet peeve)
  • With your ${...} statement in update_array(), the ${..} syntax to use a variable, not define it.

    Example:

    foo[0]=abc  # assigns 'abc' to foo[0]
    
  • Working around that the array name is stored in a variable.

    Not working:

    $1[0]=abc
    

    Working:

    declare -g "$1[0]=abc"  # -g arg is for a global variable
    
  • Passing an argument to update_array() should pass the variable name (foo in this case), not the contents of the array. foo[@] is nothing special, it is a completely normal string (in Bash).

  • Variable expansion with ${foo[@]} should be double-quoted.

Working version of the code is below:

update_array() {   
    declare -g "$1[0]=abc"
}

foo=(foo bar)

update_array foo

for i in "${foo[@]}"; do
    echo "$i"
done

## Following line added by me for further clarification
declare -p foo

which prints, correctly:

abc
bar
declare -a foo='([0]="abc" [1]="bar")'
3
  • that declaration's been confusing me.. shouldn't a declaration of variable precede the definition..
    – rusty
    Commented Jan 10, 2014 at 5:40
  • @hash declare is a bash builtin command (help declare). It is basically the same as variable assignment, declare -g "$1[0]=abc" is saying 'declare zero index of $1 to be abc' (equiv. to (in theory) $1[0]=abc)
    – kiri
    Commented Jan 10, 2014 at 5:42
  • got that.. this link suggests, "...declare/typeset are very weak form of the typing..." and may be I'll be using those only if I need to typecast my variables or other extra control..
    – rusty
    Commented Jan 10, 2014 at 6:03
0

Declaration of variables might not be necessary in Bash.1 Yes you can use declare/typeset for more control over your bash variables. So I reckon you don't have to create a function just for the purpose of declaring a new array.

This script below demonstrates a direct defining of array:

#!/bin/bash
function define_array_elements() {
# You can note the array elements being defined directly, without a prior 
# definition of the variable.
for i in {1..10}; do
    var_name[$i]="Field $i of the list"
done
}

define_array_elements > /dev/null

for i in {1..10}; do
    echo "Field $i is: ${var_name[$i]}"
done

(An example borrowed from How to declare an array but not define it? with just a little modification.)

1
  • Which version of bash does this apply to? Commented Sep 20, 2014 at 11:51
0

Short answer is: you cannot. Bash does not have a way to pass variables by reference, so there's no generic way of doing it; you're left with (ugly) hacks including indirection and/or eval.

The upcoming bash 4.3 will introduce nameref variables, which allow you to pass variables by reference, but even this feature falls short since you still risk name collition.

# example of passing variables by reference in bash 4.3
update_array() {
    declare -n array=$1
    array[0]=abc
}

foo=( foo bar )

update_array foo

printf '<%s>\n' "${foo[@]}" # outputs <abc> and <bar>

In that example, if the array was named array instead of foo, it would fail since declare -n array=array is an error (declare: array: nameref variable self references not allowed).

See http://mywiki.wooledge.org/BashFAQ/006 for other hacks.

You must log in to answer this question.

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