aboutsummaryrefslogtreecommitdiff
path: root/lume/src/notes/2024/bash-hashmap.mdx
blob: 61c4685f560696f2d160631b0121a58fe3a91626 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
---
title: Today I learned that bash has hashmaps
date: 2024-01-15
tags:
  - bash
  - til
  - crimes
---

Hashmaps (associative arrays) are a great way to store a bag of key-value data. At work I was writing something that needed me to spawn a bunch of GPU instances, GPU availability is spread out by region and GPU type. I wanted to store a mapping of GPU kind to region name and for some reason I thought it would be a good idea to do it in bash. I was horrified to find out that bash has hashmaps, and decided to write this note to tell you how to use them.

Here's how you do it:

First, declare the hashmap with the `declare` builtin:

```shell
# -A means associative array (hashmap)
declare -A FLY_REGIONS
```

Then add some values into it [from the fly.io documentation](https://fly.io/docs/gpus/gpu-quickstart/):

```shell
FLY_REGIONS["a100-40gb"]="ord"
FLY_REGIONS["a100-80gb"]="mia"
FLY_REGIONS["l40s"]="ord"
```

You can also predeclare the array with values in a read-only state:

```sh
# -A means associative array (hashmap)
# -r means read-only
declare -A -r FLY_REGIONS=(
  ["a100-40gb"]="ord"
  ["a100-80gb"]="mia"
  ["l40s"]="ord"
)
```

You can look up values with the same syntax you used to set them:

```shell
echo "${FLY_REGIONS["a100-40gb"]}" # ord
```

You can iterate over the keys with a `for` loop on the `@` value:

```shell
for size in "${!FLY_REGIONS[@]}"; do
  echo "size: $size, region: ${FLY_REGIONS[$size]}"
done
```

You can iterate over the values with a `for` loop on the `*` value:

```shell
for region in "${FLY_REGIONS[*]}"; do
  echo "region: $region"
done
```

You can delete individual keys with `unset`:

```shell
unset FLY_REGIONS["a100-40gb"]
```

If you need to delete the entire hashmap, you can also do it with `unset`:

```shell
unset FLY_REGIONS
```

Please don't use this for evil.