**NOTE**

This is a stolen article from [opensource.com](https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays)
about bash scripting. It's a good article and I've decided to use it to test my
markdown rendering.

# Bash scripting

[TOC]

| very   | important | table     |
|--------|-----------|-----------|
| v      | i         | t         |
| yes    | super     | important |
| really | really    | really    |

## Wait, but why?

Writing about Bash is challenging because it's remarkably easy for an article
to devolve into a manual that focuses on syntax oddities. Rest assured,
however, the intent of this article is to avoid having you RTFM.

## A real (actually useful) example

To that end, let's consider a real-world scenario and how Bash can help:
You are leading a new effort at your company to evaluate and optimize the
runtime of your internal data pipeline. As a first step, you want to do a
parameter sweep to evaluate how well the pipeline makes use of threads. For
the sake of simplicity, we'll treat the pipeline as a compiled C++ black box
where the only parameter we can tweak is the number of threads reserved for
data processing: `./pipeline --threads 4.`

## The basics

The first thing we'll do is define an array containing the values of the
`--threads` parameter that we want to test:

```bash
allThreads=(1 2 4 8 16 32 64 128)
```

In this example, all the elements are numbers, but it need not be the
case—arrays in Bash can contain both numbers and strings, e.g., `myArray=(1
2 "three" 4 "five")` is a valid expression. And just as with any other Bash
variable, make sure to leave no spaces around the equal sign. Otherwise,
Bash will treat the variable name as a program to execute, and the `=` as its
first parameter!

Now that we've initialized the array, let's retrieve a few of its
elements. You'll notice that simply doing `echo $allThreads` will output only
the first element.

To understand why that is, let's take a step back and revisit how we usually
output variables in Bash. Consider the following scenario:

```bash
type="article" echo "Found 42 $type"
```

Say the variable $type is given to us as a singular noun and we want to add
an `s` at the end of our sentence. We can't simply add an s to `$type` since
that would turn it into a different variable, `$types`. And although we could
utilize code contortions such as `echo "Found 42 "$type"s"`, the best way
to solve this problem is to use curly braces: `echo "Found 42 ${type}s"`,
which allows us to tell Bash where the name of a variable starts and ends
(interestingly, this is the same syntax used in JavaScript/ES6 to inject
variables and expressions in template literals).

So as it turns out, although Bash variables don't generally require curly
brackets, they are required for arrays. In turn, this allows us to specify
the index to access, e.g., `echo ${allThreads[1]}` returns the second element
of the array. Not including brackets, e.g.,`echo $allThreads[1]`, leads Bash
to treat `[1]` as a string and output it as such.

Yes, Bash arrays have odd syntax, but at least they are zero-indexed, unlike
some other languages (I'm looking at you, R).[^1]

## Looping through arrays

Although in the examples above we used integer indices in our arrays, let's
consider two occasions when that won't be the case: First, if we wanted the
$i-th element of the array, where $i is a variable containing the index of
interest, we can retrieve that element using: echo ${allThreads[$i]}. Second,
to output all the elements of an array, we replace the numeric index with
the @ symbol (you can think of @ as standing for all):

```bash
type="article"
echo "Found 42 $type"
```

*[RTFM]: Read the Fucking Manual
*[HTML]: Hyper Text Markup Language

[^1]: Example Footnote
