gawa/gawa/blog/data/articles/en-bash-arrays.md
2023-10-03 15:48:22 +02:00

3.8 KiB

NOTE

This is a stolen article from opensource.com 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

cool math: 1+2 \le \frac{1}{2} cool math: 1+2 \le \frac{1}{2}

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:

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:

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):

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

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


  1. Example Footnote ↩︎