Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

how to pass array into function and updates to array are reflected outsite function

Writer Matthew Barrera

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

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

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

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 for other hacks.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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