Home > front end >  Bash associative array in array
Bash associative array in array

Time:04-02

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 ?

CodePudding user response:

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

CodePudding user response:

You can simulate multi-dimensional array like this :

#!/usr/bin/env bash
  
declare -A task1=([uri]="https://example1.com" [schedule]="0 5 * * *")
declare -A task2=([uri]="https://example2.com" [schedule]="0 10 * * *")

declare -a tasks=(task1 task2)
declare -n task

for task in "${tasks[@]}"; do
    echo "task uri=${task[uri]}"
    echo "task schedule=${task[schedule]}"
done
  •  Tags:  
  • bash
  • Related