16

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?

0

3 Answers 3

14

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.' ) )
1
  • line 1: unexpected EOF while looking for matching `)' ¯\_(ツ)_/¯ Commented Mar 31, 2023 at 18:22
5

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
0

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.