Thursday, April 7, 2022

[SOLVED] Bash associative array in array

Issue

I made a script to create Google Cloud Scheduler tasks. I want to create a loop in bash to not repeat all the commands so I made this:

#!/bin/bash

declare -A tasks

tasks["task1"]="0 5 * * *"
tasks["task2"]="0 10 * * *"

for key in ${!tasks[@]}; do
    gcloud scheduler jobs delete ${key} --project $PROJECT_ID --quiet
    gcloud scheduler jobs create http ${key} --uri="https://example.com" --schedule="${tasks[${key}]}" --project $PROJECT_ID --http-method="get"
done

In this loop I just use my array key to give a name to the cron and I'm using the value ${tasks[${key}]} for the cron pattern.

But now I have a problem because I want to set a different --uri by task. E.g I want https://example1.com for the task1 and https://example2.com for the task2 etc...

So the I'd like to add another key inside the task array like :

tasks["task1"]["uri"]="https://example1.com"
tasks["task1"]["schedule"]="0 5 * * *"

tasks["task2"]["uri"]="https://example2.com"
tasks["task2"]["schedule"]="0 10 * * *"

And use this in my loop. How can I do that ? Or maybe there is a better way in bash to manager my problem ?


Solution

bash doesn't support multi-dimensional arrays; what you might want to consider is 2 arrays that use the same index for corresponding entries, eg:

declare -A uri schedule

uri["task1"]="https://example1.com"
schedule["task1"]="0 5 * * *"

uri["task2"]="https://example2.com"
schedule["task2"]="0 10 * * *"

Since both arrays use the same set of indices you can use a single for loop to process both arrays, eg:

for key in "${!schedule[@]}"               # or: for key in "${!uri[@]}"
do
    echo "${key} : ${schedule[${key}]} : ${uri[${key}]}"
done

This generates:

task1 : 0 5 * * * : https://example1.com
task2 : 0 10 * * * : https://example2.com


Answered By - markp-fuso
Answer Checked By - Cary Denson (WPSolving Admin)