In this lesson, you will learn how to maintain memory of previous iterations within a loop to make logic decisions based on the "history" of your data.
The Concept of "State" in Iteration
Standard loops process one item at a time, oblivious to what came before. However, complex scripts often require you to "remember" information from the previous pass to determine what to do in the current pass. This is called Stateful Loop Control.
Think of a stateful loop as a conversation with your script. Each iteration tells the script something new, and the script uses a variable (a "flag" or "tracker") to store that context so it can handle the next item correctly.
Practical Illustration: Tracking Changes
Imagine you are reading a log file where multiple entries for the same "User ID" appear in a row. You want to trigger an action only when the User ID changes. To do this, you must store the "previous" ID in a variable to compare it against the "current" ID.
#!/bin/bash
# A simple list of User IDs
users=("101" "101" "102" "103" "103")
# Initialize our state variable
previous_user=""
for current_user in "${users[@]}"; do
# Check if the state has changed since the last loop
if [[ "$current_user" != "$previous_user" ]]; then
echo "Processing new user: $current_user"
fi
# Update the state to the current value for the next cycle
previous_user="$current_user"
done
Why This Matters
Without this previous_user variable, the loop would treat every line as a fresh start. By "saving" the state at the end of every loop iteration (previous_user="$current_user"), you create a bridge between the past and the future.
This pattern is fundamental for:
- Detecting transitions: Triggering alerts when a value shifts from "OK" to "FAIL."
- Summarizing chunks: Calculating totals for a specific group until a new group begins.
- Filtering duplicates: Skipping lines that match the preceding record.
By managing state, you transform a series of disconnected commands into a cohesive logical flow that understands the structure of the data it is processing.
Key Takeaway: To track state, initialize a tracker variable outside your loop, perform your logic using that variable, and always update it at the end of the loop cycle.