How to pass an array argument to the Bash script

75,497

Solution 1

Bash arrays are not "first class values" -- you can't pass them around like one "thing".

Assuming test.sh is a bash script, I would do

#!/bin/bash
arg1=$1; shift
array=( "$@" )
last_idx=$(( ${#array[@]} - 1 ))
arg2=${array[$last_idx]}
unset array[$last_idx]

echo "arg1=$arg1"
echo "arg2=$arg2"
echo "array contains:"
printf "%s\n" "${array[@]}"

And invoke it like

test.sh argument1 "${array[@]}" argument2

Solution 2

Have your script arrArg.sh like this:

#!/bin/bash

arg1="$1"
arg2=("${!2}")
arg3="$3"
arg4=("${!4}")

echo "arg1=$arg1"
echo "arg2 array=${arg2[@]}"
echo "arg2 #elem=${#arg2[@]}"
echo "arg3=$arg3"
echo "arg4 array=${arg4[@]}"
echo "arg4 #elem=${#arg4[@]}"

Now setup your arrays like this in a shell:

arr=(ab 'x y' 123)
arr2=(a1 'a a' bb cc 'it is one')

And pass arguments like this:

. ./arrArg.sh "foo" "arr[@]" "bar" "arr2[@]"

Above script will print:

arg1=foo
arg2 array=ab x y 123
arg2 #elem=3
arg3=bar
arg4 array=a1 a a bb cc it is one
arg4 #elem=5

Note: It might appear weird that I am executing script using . ./script syntax. Note that this is for executing commands of the script in the current shell environment.

Q. Why current shell environment and why not a sub shell?
A. Because bash doesn't export array variables to child processes as documented here by bash author himself

Solution 3

You can write your array to a file, then source the file in your script. e.g.:

array.sh

array=(a b c)

test.sh

source $2
...

Run the test.sh script:

./test.sh argument1 array.sh argument3
Share:
75,497
zhihong
Author by

zhihong

Updated on July 26, 2022

Comments

  • zhihong
    zhihong almost 2 years

    It is surprising me that I do not find the answer after 1 hour search for this. I would like to pass an array to my script like this:

    test.sh argument1 array argument2
    

    I DO NOT want to put this in another bash script like following:

    array=(a b c)
    for i in "${array[@]}"
    do
      test.sh argument1 $i argument2
    done
    
  • glenn jackman
    glenn jackman about 11 years
    what if any of the array elements contain whitespace?
  • doubleDown
    doubleDown about 11 years
    Great answer. I know this doesn't conform to OP's requirement of test.sh argument1 array argument2 but if the invocation was changed to test.sh argument1 argument2 array (the array being the last), it'd be less work.
  • anubhava
    anubhava about 11 years
    Good answer. But technically it is not passing array to a script. What if OP needs to pass 2 array variables to this script like test.sh argument1 array1 array2
  • zhihong
    zhihong about 11 years
    @anubhava, thanks very much. The elements of my array have no space. But both yours and glenn's answers are nice.
  • bballdave025
    bballdave025 about 5 years
    Note that you need to declare the array before calling the script. For the OP, this would mean $ array=(a b c) and then test.sh argument1 "${array[@]}" argument2 . It might only be me who had to think about that a bit, but I'm commenting in the hope that it will help someone.
  • frp farhan
    frp farhan about 5 years
    When i run your code, arg2=("${!2}") for this line i am getting Bad Substitution
  • ErikE
    ErikE almost 5 years
    This is super, super clever and made my shells scripts awesome!