Search code examples
arraysbashshellgetopts

bash - using getopts with an associative array in a bash script


I'm using getopts along with an associate array in my code below. What I can't figure out is how to correctly call my values, given that I'm asking for (2) alias(s) using the same flag.

Here's what I have so far:

#!/bin/bash

set -e

usage () {
    echo "Usage: $0 -c alias1  -c alias2"
}

while getopts ":c:" opt; do
  case $opt in
    c) alias="$OPTARG";;
    *) echo "Error unknown option -$OPTARG"
       usage
       exit 1
       ;;
  esac
done

# Testing use off array
declare -A alias=( [alias1]=myhost-01.com \
                   [alias2]=myhost-02.com \
                   [alias3]=myhost-03.com \
                   [alias4]=myhost-04.com )

echo "This is my source host:${alias}"
echo "This is my target host:${alias}"

This is how I would like to execute it (or better suggeested way):

-bash-4.1$ ./test-array2.sh -c alias1 -c alias4
This is my source host:
This is my target host:

Obviously, I'm not getting my expected result which would be this:

This is my source host: myhost-01.com
This is my target host: myhost-04.com

How can I do this? I want to pass in (2) aliases which uses my alias mapping (associative array) to grab the correct key value pair or maybe my approach is wrong and I can't use -c twice? Thanks.


Solution

  • You could use an array to store the aliases e.g.

    aliases=()
    while getopts ":c:" opt; do
        case $opt in
            c) aliases+=( "$OPTARG" );;
        # ...
        esac
    done
    

    And then you use the this array to index your associative array:

    echo "This is my source host:${alias_to_host[${aliases[0]}]}"
    echo "This is my target host:${alias_to_host[${aliases[1]}]}"
    

    But if the input options are representing aliases for source and destination host and there always is exactly two hosts, it would be much cleaner to use separate options (e.g. -s and -d) and separate variables for these than reusing the switch -c:

    # ...
        case $opt in
            s) source=$OPTARG;;
            d) destination=$OPTARG;;
            # ...
        esac
    # ...
    
    echo "This is my source host:${alias_to_host[$source]}"
    echo "This is my target host:${alias_to_host[$destination]}"