You have a problem with passing the array as one of the parameter for the -a
flag. Arrays in bash
get expanded in command line before the actual script is invoked. The "${array[@]}"
expansions outputs words separated by white-space
So your script is passed as
-a "E1" "E2" "E3" -p foo -c bar
So with the getopts()
call to the argument OPTARG
for -a
won't be populated with not more than the first value, i.e. only E1
. One would way to achieve this is to use the array expansion of type "${array[*]}"
which concatenates the string with the default IFS
(white-space), so that -a
now sees one string with the words of the array concatenated, i.e. as if passed as
-a "E1 E2 E3" -p foo -c bar
I've emphasized the quote to show arg for -a
will be received in getopts()
#!/usr/bin/env bash
while getopts ":a:p:c:" opt; do
case $opt in
a) ARRAY="${OPTARG}";;
p) PARAM1="${OPTARG}";;
c) PARAM2="${OPTARG}";;
\?) exit "Invalid option -$OPTARG";;
esac
done
# From the received string ARRAY we are basically re-constructing another
# array splitting on the default IFS character which can be iterated over
# as in your input example
read -r -a splitArray <<<"$ARRAY"
for a in "${splitArray[@]}"; do
echo "$a"
done
echo "$PARAM1"
echo "$PARAM2"
and now call the script with args as. Note that you are using param1
and param2
are variables but your definition seems to show it as an array. Your initialization should just look like
arr=("E1" "E2" "E3")
param1="foo"
param2="bar"
and invoked as
-a "${arr[*]}" -p "$param1" -c "$param2"
A word of caution would be to ensure that the words in the array arr
don't already contain words that contain spaces. Reading them back as above in that case would have a problem of having those words split because the nature of IFS
handling in bash
. In that case though use a different de-limiter say |
, #
while passing the array expansion.