Shell Scripting & CLI Tools: From the Command Line to Real Automation
Section 12 of 18

Arrays and Arithmetic in Bash

Now that we know how to write robust scripts, let's expand our data-handling toolkit with arrays. Once your scripts start dealing with collections of files, arguments, configuration values, or results from commands, you quickly realize that cramming everything into a single string is a nightmare. Arrays let us hold multiple values in a single named container, which is both cleaner and much safer.

Indexed Arrays

Arrays let you store multiple values in a single variable:

# Declare and initialize
fruits=("apple" "banana" "cherry")
files=()   # Empty array

# Access elements
echo "${fruits[0]}"     # apple (0-indexed)
echo "${fruits[2]}"     # cherry
[echo "${fruits[-1]}"    # cherry (last element, Bash 4+)](https://www.gnu.org/software/bash/manual/html_node/Arrays.html)

# Append to array
fruits+=("date")
fruits+=("elderberry" "fig")

# Get all elements
echo "${fruits[@]}"     # apple banana cherry date elderberry fig

# Get number of elements
echo "${#fruits[@]}"    # 6

# Get all indices
echo "${!fruits[@]}"    # 0 1 2 3 4 5

# Iterate
for fruit in "${fruits[@]}"; do
    echo "  - $fruit"
done

[# Slice (start at index 1, take 3 elements)
echo "${fruits[@]:1:3}"   # banana cherry date](https://www.gnu.org/software/bash/manual/html_node/Arrays.html)

The double-quoting "${fruits[@]}" is critical — it preserves each element as a separate word, even if elements contain spaces. (Use "${fruits[*]}" instead, and all elements get joined with the first character of IFS. Usually not what you want.)

### Associative Arrays (Bash 4+)

Associative arrays use string keys instead of numeric indices — essentially a hash map built right into the shell:

declare -A user_info
user_info["name"]="Alice"
user_info["email"]="[email protected]"
user_info["age"]=30

# Access
echo "${user_info[name]}"

# Check if key exists
if [[ -v user_info["email"] ]]; then
    echo "Email: ${user_info[email]}"
fi

# Iterate over key-value pairs
for key in "${!user_info[@]}"; do
    echo "$key = ${user_info[$key]}"
done

Arithmetic

Bash has built-in integer arithmetic through ((...)):

# Arithmetic evaluation
result=$((2 + 3))          # 5
result=$((10 * 3 - 5))     # 25
result=$((17 % 5))         # 2 (modulo)
result=$((2 ** 8))         # 256 (exponentiation)

# Increment/decrement
((count++))
((count--))
((count += 10))

# In conditions (non-zero = true, which is the OPPOSITE of exit codes)
if (( x > 10 && y < 20 )); then
    echo "Condition met"
fi

{% element elem_elaboration_11_3_c2e037 %}


# Arithmetic with bc for floating point
result=$(echo "scale=2; 22/7" | bc)   # 3.14

Bash only does integer arithmetic natively — that's the one limitation. For floating-point math, reach for bc or awk:

# Using awk for floating point
pi=$(awk 'BEGIN {printf "%.10f", atan2(0,-1)}')
echo "Pi is approximately: $pi"