Returning an array from a Bash function

For those of you who are still learning Bash (including me…), I’m sure one of the things you would have asked yourself is "How on earth do I return an array from a bash function?".

Well I’ve written a small script that will explain this:

(Please see update below)

#!/bin/bash
IFS=$'nt'

function fnGo () {
	array=(
		a	s	d	f	
		"gh ij"	"kl mn"
	)
	echo "${array[*]}"
}

# -------- out - String variable --------
out=$(fnGo)
echo ""out" isn't an array: ${out[1]} - nothing"

echo $'n'""out" Works with iteration:"
for item in $out; do
	echo "item:"$'t'"$item"
done

# -------- out2 - An array --------
out2=($(fnGo))
echo $'n'""out2" now an array:"
for ((i=0; i<${#out2[*]}; i++)); do
	echo "item $i:"$'t'"${out2[i]}"
done

echo $'n'"Though "out2" cannot be iterated anymore...:"
for item in $out2; do
	echo "item:"$'t'"$item"
done


Basically, it’s exactly as you’d do for returning a single value from a function (use echo) – but, you need to make sure you surround the variable with quotes (in the function – echo "${array[*]}"), and receive it as an array – out2=($(fnGo)).


Note you can only either choose to use an iterator method (out1), or an addressing method (out2), but not both – run the script and you’ll see what I mean.

Oh, one more thing (just as a tip for those who don’t already know) – pay attention to your IFS variable (which determines how parameters are separated)! This is especially important if you’re taking in quoted (escaped) command-line parameters that may have a space in them (such as file names) – in that case, I normally use "n".

—- Update (2009-10-03 @ 10:35:27) —-

Ok, having written bash scripts for a little while now, I have found a better way of doing this by using a special "return" variable; the old method will not let you actually echo anything onto the console and do things like "exit 1", but the following will:

#!/bin/bash
IFS=$'nt'

rtr=""

function fnGo () {
	local array=()	# You can use array="" - it won't make any difference
	echo "fnGo() called"
	array=(
		a	s	d	f	
		"gh ij"	"kl mn"
	)
	rtr=(${array[@]})
}

# -------- out - String variable --------
fnGo
out="${rtr[*]}"
echo ""out" isn't an array: "'${out[1]}'"="${out[1]}" - nothing"

echo $'n'""out" Works with iteration:"
for item in $out; do
	echo "item:"$'t'"$item"
done

echo -e "n"

# -------- out2 - An array --------
fnGo
out2=(${rtr[@]})
echo -e ""out2" now an array:"
for ((i=0; i<${#out2[@]}; i++)); do
	echo "item $i:"$'t'"${out2[i]}"
done

echo $'n'"Though "out2" cannot be iterated anymore...:"
for item in $out2; do
	echo "item:"$'t'"$item"
done

You may also want to check out this article for the difference in the use of the [*] and [@] for enumeration.

Advertisements

3 Responses to “Returning an array from a Bash function”

  1. Sibi JV Says:

    Instead of globals , can i use local. Itried something like one below. It returns the array with all values ( actually as a string rather than array)

    #!/bin/bash

    function abc
    {
    local abc_de_variable=$1
    local myvar=( {abc} {test local from abc} )
    eval $abc_de_variable=”‘${myvar[@]}'”
    }

    function de
    {
    local de_variable
    abc de_variable

    for item in “${de_variable[@]}”; do
    printf “%s\n” “${item}”
    done
    }

    de

    • Sibi JV Says:

      Hi
      Following works, but still in my case the second index elemet which is the string “test local from abc” gets split since it has spaces. This needs to be resolved

      #!/bin/bash

      function abc
      {
      local abc_de_variable=$1
      local myvar=( abc “test local from abc” )
      eval $abc_de_variable=”( ${myvar[@]} )”
      }

      function de
      {
      local de_variable
      abc de_variable

      local len=”${#de_variable[@]}”
      echo $len

      for item in “${de_variable[@]}”; do
      printf “%s\n” “${item}”
      done
      }

      de

  2. sibi Says:

    my mistake in defining strings

    function abc
    {
    local abc_de_variable=$1
    local myvar=( “abc” \”test local from abc\” )
    eval $abc_de_variable=”( ${myvar[@]} )”
    }


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: