Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I pass an array as a variable from a first bash shell script to a second script.

first.sh
#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
sh second.sh "$AR" # foo
sh second.sh "${AR[@]}" # foo
second.sh
#!/bin/bash
ARR=$1
echo ${ARR[@]}

In both cases, the result is foo. But the result I want is foo bar baz bat.

What am I doing wrong and how do I fix it?

share|improve this question
up vote 3 down vote accepted

AFAIK, you can't. You have to serialize it and deserialize it, e.g. via the argument array:

first

#!/bin/bash
ar=('foo' 'bar' 'baz' 'bat')
second "${ar[@]}" #this is equivalent to: second foo bar baz bat

second

#!/bin/bash
arr=( "$@" )
printf ' ->%s\n' "${arr[@]}"
<<PRINTS
   -> foo
   -> bar
   -> baz
   -> bat
PRINTS

A little bit of advice:

  • reserve all caps for exported variables
  • unless you have a very good specific reason for not doing so "${someArray[@]}" should always be double quoted; this formula behaves exactly like 'array item 0' 'array item 1' 'aray item 2' 'etc.' (assuming someArray=( 'array item 0' 'aray item 1' 'aray item 2' 'etc.' ) )
share|improve this answer

The AR array is passed via the first argument to second.sh.

first.sh

#!/bin/bash
AR=('foo' 'bar' 'a space' 'bat')
printf "AR array contains %d elements: " ${#AR[@]}
printf "%s " "${AR[@]}"
printf "\n"
./second.sh "$AR"
./second.sh "$(printf "(" ; printf "'%s' " "${AR[@]}" ; printf ")")"

Note that sh is not used anymore to run the second.sh script.

These chained printf are used to forge a single parameter that will be safe if some array elements contain space chars.

second.sh

#!/bin/bash
declare -a ARR=$1
printf "ARR array contains %d elements: " ${#ARR[@]}
printf "%s " "${ARR[@]}"
printf "\n"

----

For a solution where the AR array is passed using any number of arguments to the second.sh script.

first.sh

#!/bin/bash
AR=('foo' 'bar' 'a space' 'bat')
printf "AR array contains %d elements: " ${#AR[@]}
printf "%s " "${AR[@]}"
printf "\n"
./second.sh "$AR"
./second.sh "${AR[@]}"

second.sh

#!/bin/bash
ARR=( "$@" )
printf "ARR array contains %d elements: " ${#ARR[@]}
printf "%s " "${ARR[@]}"
printf "\n"

----

The test:

$ chmod +x *sh
$ ./first.sh
AR array contains 4 elements: foo bar a space bat
ARR array contains 1 elements: foo
ARR array contains 4 elements: foo bar a space bat
share|improve this answer

first

#!/bin/bash
ar=('foo' 'bar' 'baz' 'bat')
./second "${ar[@]}"

second

#!/bin/bash
read -a arr1 <<< "${BASH_ARGV[@]}"
echo "${arr1[@]}"

This should have been enough, but the array order is reversed so I added:

for (( i=${#arr1[@]}-1,j=0 ; i>=0 ; i--,j++ ))
do
    arr2[j]="${arr1[i]}"
done
echo "${arr2[@]}"

read -a reads input into array arr1, but for some reason I can't figure out, the array is reversed, so I reverse it back into arr2.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.