Skip to content

Arrays

Arrays are fundamental data structures in bash that allow you to store and manipulate collections of values. This chapter covers indexed arrays in detail, including declaration, access, manipulation, and practical applications for DevOps workflows.


Arrays are ordered collections of elements, each accessed by an index. In bash, arrays can hold strings, numbers, or a mix of both.

┌─────────────────────────────────────────────────────────────────────┐
│ BASH ARRAY STRUCTURE │
└─────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ Index: 0 1 2 3 4 │
│ Values: ["apple"] ["banana"] ["cherry"] ["date"] ["elderberry"] │
│ │
│ Array Name: fruits │
│ │
│ fruits[0] = "apple" │
│ fruits[1] = "banana" │
│ fruits[2] = "cherry" │
│ fruits[3] = "date" │
│ fruits[4] = "elderberry" │
│ │
└───────────────────────────────────────────────────────────────────────┘

array_declare.sh
#!/usr/bin/env bash
# Declare and initialize array
fruits=("apple" "banana" "cherry")
echo "First element: ${fruits[0]}"
echo "Second element: ${fruits[1]}"
echo "Third element: ${fruits[2]}"
array_index.sh
#!/usr/bin/env bash
# Create array with specific indices
colors[0]="red"
colors[2]="blue" # Can skip indices
colors[1]="green"
echo "${colors[@]}" # Output: red green blue
array_declare2.sh
#!/usr/bin/env bash
# Declare array
declare -a numbers
# Add elements
numbers[0]=1
numbers[1]=2
numbers[2]=3
array_from_command.sh
#!/usr/bin/env bash
# Create array from command output
files=($(ls -1 /etc/*.conf 2>/dev/null | head -5))
echo "Found ${#files[@]} config files"
for file in "${files[@]}"; do
echo " $file"
done

array_access.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry" "date")
# Access single element
echo "${fruits[0]}" # apple
echo "${fruits[1]}" # banana
echo "${fruits[2]}" # cherry
# Negative indexing (bash 4+)
echo "${fruits[-1]}" # date (last element)
echo "${fruits[-2]}" # cherry (second to last)
array_all.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry")
# All elements as separate words
echo "${fruits[@]}" # apple banana cherry
# All elements as single word
echo "${fruits[*]}" # apple banana cherry
# With expansion
echo "Fruits: ${fruits[@]}"

array_length.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry")
# Length of array
echo "${#fruits[@]}" # 3
# Length of element
echo "${#fruits[0]}" # 5 (length of "apple")
array_add.sh
#!/usr/bin/env bash
fruits=("apple" "banana")
# Add single element
fruits+=("cherry")
# Add multiple elements
fruits+=("date" "elderberry")
echo "${fruits[@]}"
array_remove.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry")
# Remove element by index
unset fruits[1] # Removes "banana"
echo "${fruits[@]}" # apple cherry
# Remove entire array
# unset fruits
# Reindex array after removal
fruits=("${fruits[@]}")
array_slice.sh
#!/usr/bin/env bash
numbers=(1 2 3 4 5 6 7 8 9 10)
# Slice: from index 2, take 3 elements
echo "${numbers[@]:2:3}" # 3 4 5
# From index to end
echo "${numbers[@]:5}" # 6 7 8 9 10
# First 3 elements
echo "${numbers[@]:0:3}" # 1 2 3

array_iterate.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry")
# Iterate over elements
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done
echo "---"
# Iterate with index
for i in "${!fruits[@]}"; do
echo "Index $i: ${fruits[$i]}"
done
array_while.sh
#!/usr/bin/env bash
fruits=("apple" "banana" "cherry")
i=0
while [ $i -lt ${#fruits[@]} ]; do
echo "Fruit $i: ${fruits[$i]}"
i=$((i + 1))
done

process_servers.sh
#!/usr/bin/env bash
# List of servers
servers=(
"web01.example.com"
"web02.example.com"
"db01.example.com"
"db02.example.com"
)
echo "Checking ${#servers[@]} servers..."
# Check each server
for server in "${servers[@]}"; do
if ping -c 1 -W 2 "$server" &>/dev/null; then
echo "$server is reachable"
else
echo "$server is not reachable"
fi
done
config_arrays.sh
#!/usr/bin/env bash
# Define services with their ports
declare -A services
services=(
["nginx"]=80
["postgresql"]=5432
["redis"]=6379
["elasticsearch"]=9200
)
# List all services
echo "Available services:"
for service in "${!services[@]}"; do
echo " $service on port ${services[$service]}"
done
# Check if service exists
check_service() {
local service="$1"
if [ -n "${services[$service]:-}" ]; then
echo "$service is configured on port ${services[$service]}"
else
echo "Service $service not found"
fi
}
check_service "nginx"
check_service "mysql"

Example 3: Command-Line Arguments as Array

Section titled “Example 3: Command-Line Arguments as Array”
args_array.sh
#!/usr/bin/env bash
# Access arguments as array
echo "Number of arguments: $#"
echo "All arguments: ${@}"
# Process each argument
for arg in "${@}"; do
echo "Argument: $arg"
done
# Using array slice
echo "First 3 arguments: ${@:1:3}"
echo "Arguments starting from 2: ${@:2}"
file_filter.sh
#!/usr/bin/env bash
# Get all log files
mapfile -t log_files < <(find /var/log -maxdepth 1 -name "*.log" 2>/dev/null)
echo "Found ${#log_files[@]} log files"
# Filter files larger than 1MB
large_files=()
for file in "${log_files[@]}"; do
size=$(stat -c%s "$file" 2>/dev/null || echo 0)
if [ $size -gt 1048576 ]; then
large_files+=("$file")
fi
done
echo "Large files (>1MB): ${#large_files[@]}"
for file in "${large_files[@]}"; do
echo " $file"
done
unique_array.sh
#!/usr/bin/env bash
# Array with duplicates
data=(1 2 3 2 4 3 5 1 6)
# Get unique values
unique=($(printf '%s\n' "${data[@]}" | sort -u | tr '\n' ' '))
echo "Original: ${data[@]}"
echo "Unique: ${unique[@]}"
array_intersection.sh
#!/usr/bin/env bash
# Two arrays
array1=("apple" "banana" "cherry" "date")
array2=("banana" "date" "elderberry" "fig")
# Find common elements
common=()
for item in "${array1[@]}"; do
for item2 in "${array2[@]}"; do
if [ "$item" = "$item2" ]; then
common+=("$item")
break
fi
done
done
echo "Common elements: ${common[@]}"

array_function.sh
#!/usr/bin/env bash
# Function that accepts array
process_array() {
local arr=("$@")
echo "Received ${#arr[@]} elements"
for item in "${arr[@]}"; do
echo " Processing: $item"
done
}
fruits=("apple" "banana" "cherry")
process_array "${fruits[@]}"
array_return.sh
#!/usr/bin/env bash
# Function that returns array
get_servers() {
local servers=("server1" "server2" "server3")
echo "${servers[@]}"
}
# Capture returned array
mapfile -t server_list < <(get_servers)
echo "Servers: ${server_list[@]}"

mapfile_example.sh
#!/usr/bin/env bash
# Read lines into array
mapfile -t lines < /etc/passwd
echo "First 5 lines:"
for i in {0..4}; do
echo "Line $i: ${lines[$i]}"
done
# Read with delimiter
mapfile -t -d ':' fields < <(echo "field1:field2:field3")
echo "Fields: ${fields[@]}"

assoc_basic.sh
#!/usr/bin/env bash
# Must declare before use (bash 4+)
declare -A user_info
# Add key-value pairs
user_info["name"]="John Doe"
user_info["email"]="john@example.com"
user_info["role"]="admin"
# Access values
echo "Name: ${user_info[name]}"
echo "Email: ${user_info[email]}"
# Get all keys
echo "Keys: ${!user_info[@]}"

array_quotes.sh
#!/usr/bin/env bash
# WRONG - can cause word splitting
files=(*.txt)
rm ${files[@]} # Dangerous
# CORRECT - properly quoted
rm "${files[@]}" # Safe
mapfile_t.sh
#!/usr/bin/env bash
# Always use -t to remove trailing newlines
mapfile -t lines < file.txt
# Without -t, trailing newline is included
mapfile lines < file.txt

In this chapter, you learned about:

  • ✅ Array declaration methods
  • ✅ Accessing array elements
  • ✅ Array operations (add, remove, slice)
  • ✅ Array iteration
  • ✅ Practical DevOps examples
  • ✅ Array functions
  • ✅ Mapfile/readarray
  • ✅ Associative arrays preview
  • ✅ Best practices

  1. Create an array of your favorite fruits and print them
  2. Add and remove elements from an array
  3. Iterate over array with index
  1. Create a script that processes server list
  2. Implement a function that accepts array arguments
  3. Filter array elements based on condition
  1. Create a unique value function for arrays
  2. Implement array intersection
  3. Build a configuration system using arrays

Continue to the next chapter to learn about associative arrays in detail.


Previous Chapter: Loop Control Next Chapter: Associative Arrays