Loops in Shell Scripting (For, While, and Dynamic Automation)
Loops are fundamental control structures in shell scripting that allow you to execute a block of code repeatedly based on a condition or a range. Instead of manually writing repetitive commands, loops enable DevOps engineers to automate tasks like bulk directory creation, system monitoring, and log processing efficiently.
1. What is a Loop? (The Mental Model)
A loop is a programming construct that repeats a set of instructions until a specific termination condition is met. If no termination condition is defined or met, the loop runs indefinitely.
Real-Life Analogy: The "Bhupendra Jogi" Loop
To understand how an uncontrolled or infinite loop works, consider the viral Indian social media meme of Bhupendra Jogi:
Interviewer: "What is your name?" Interviewee: "Bhupendra Jogi." Interviewer: "Where have you been in the US?" Interviewee: "Bhupendra Jogi." Interviewer: "What is your name?" Interviewee: "Bhupendra Jogi..."
Without an explicit exit condition or a change in state, the conversation gets stuck in a repetitive cycle. In shell scripting, we must define precise entry, execution, and exit conditions to prevent scripts from running infinitely and consuming system resources.
2. The Naive vs. Loop-Based Approach
The Problem: Creating Multiple Directories Manually
Imagine you need to create five test directories named demo1, demo2, demo3, demo4, and demo5.
The Naive Approach
A beginner might write individual commands sequentially:
mkdir demo1
mkdir demo2
mkdir demo3
mkdir demo4
mkdir demo5
- Why this fails at scale: If you need to create 90 directories (e.g., for a "90 Days of DevOps" challenge), writing 90 lines of code is tedious, error-prone, and highly inefficient to maintain.
The Loop-Based Solution
By wrapping a single mkdir command inside a loop, you can generate any number of directories dynamically with just a few lines of code.
3. The Bash for Loop Syntax & Evolution
In Bash, the for loop can be written using a C-style syntax. This syntax is highly intuitive for those coming from languages like C, C++, Java, or JavaScript.
The C-Style for Loop Syntax
for (( initialization; condition; increment/decrement ))
do
# Commands to execute
done
Step-by-Step Code Evolution
Step 1: Basic Loop Implementation
Here is a basic script (for_loop.sh) that creates 5 directories:
#!/bin/bash
# A simple loop to create 5 directories
for (( num=1; num<=5; num++ ))
do
mkdir "demo$num"
done
Note on Syntax: In Bash, C-style arithmetic evaluations inside a
forloop must be enclosed in double parentheses(( ... )). Using single parentheses or brackets will result in a syntax error.
Step 2: Executing the Script
- Give execution permissions to the script:
BASH
chmod +x for_loop.sh - Run the script:
BASH
./for_loop.sh - Verify the created directories:
BASH
ls # Output: demo1 demo2 demo3 demo4 demo5
4. Dynamic Folder Creation Using Command-Line Arguments
To make scripts reusable across different environments, you should avoid hardcoding values. Instead, pass parameters dynamically using command-line arguments ($1, $2, $3).
The Dynamic Script
This script accepts three arguments:
- Folder Prefix (
$1): The base name of the folder (e.g.,day,demo). - Start Range (
$2): The starting integer index. - End Range (
$3): The ending integer index.
#!/bin/bash
# Task: Dynamic folder creation using positional arguments
# $1 = Folder Name Prefix
# $2 = Start Range
# $3 = End Range
for (( num=$2; num<=$3; num++ ))
do
mkdir "${1}${num}"
done
Real-World Use Case: "90 Days of DevOps"
If you want to automate the creation of 90 folders for a structured learning repository, you can execute the script as follows:
./for_loop.sh day 1 90
Execution Flow:
5. Real-World Troubleshooting & Debugging
When writing shell scripts, syntax errors are common. Understanding how to interpret and fix these errors is a key debugging skill.
Common Pitfall 1: Special Characters in Comments
If you use positional parameters (like $1, $2) inside comment blocks, the Bash parser might try to evaluate them, leading to unexpected errors such as:
line 16: warning: here-document at line 16 delimited by end-of-file (wanted 'task')
- Solution: Keep comments clean and avoid using active variable syntax (like unescaped
$signs) inside them.
Common Pitfall 2: Missing Double Parentheses
Using single parentheses ( ) instead of double parentheses (( )) for C-style loops will cause a syntax error:
syntax error: unexpected token...
- Solution: Always use
(( initialization; condition; update ))for arithmetic loops.
Safe Cleanup Workflow
To clean up test directories created during experimentation without deleting critical files, use wildcards carefully:
# Delete all folders starting with "day"
rm -rf day*
# Delete all folders starting with "demo"
rm -rf demo*
6. The Bash while Loop
A while loop executes a block of code as long as a specified condition remains true. It is ideal when you do not know the exact number of iterations beforehand.
Syntax
while [ condition ]
do
# Commands to execute
# Increment/Decrement step
done
Basic while Loop Example
The following script (while_loop.sh) prints a message five times:
#!/bin/bash
num=0
# Loop runs as long as num is less than or equal to 5
while [ $num -le 5 ]
do
echo "Iteration: $num"
num=$((num + 1)) # Incrementing the variable
done
7. Arithmetic Operations & Variable Incrementing in Bash
In Bash, variables are treated as strings by default. Therefore, writing num = num + 1 literally assigns the string "num + 1" to the variable instead of performing mathematical addition.
How to Correctly Increment Variables
To perform arithmetic operations, you must use double parentheses (( ... )) or arithmetic expansion $(( ... )).
Advanced Example: Finding Even Numbers
This script combines a while loop, arithmetic evaluation, and conditional logic to print even numbers up to 10:
#!/bin/bash
num=0
while [ $num -le 10 ]
do
# Check if the number is divisible by 2
if [ $((num % 2)) -eq 0 ]
then
echo "$num is an Even Number"
fi
# Increment step
num=$((num + 1))
done
8. Complete Flow Walkthroughs
For Loop Execution Flow (for_loop.sh day 1 3)
9. Loop Comparison Matrix
Summary and Key Takeaways
- Loops Prevent Redundancy: Loops allow you to write DRY (Don't Repeat Yourself) code, replacing hundreds of manual commands with a few lines of script.
- C-Style Syntax in Bash: Use double parentheses
(( ... ))for C-style loops:for (( i=1; i<=n; i++ )). - Dynamic Arguments: Positional parameters (
$1,$2,$3) allow you to pass folder names and ranges dynamically at runtime. - While Loop Conditionals: Use
while [ condition ]to run loops based on logical evaluations (e.g.,-lefor less than or equal to,-eqfor equal to). - Arithmetic in Bash: Always use arithmetic expansion
$(( expression ))or double parentheses(( expression ))to perform mathematical operations like increments (num++) or modulo calculations (num % 2). - Safe Testing Practices: When testing scripts that create directories or files in bulk, use targeted wildcards (e.g.,
rm -rf demo*) to clean up your workspace safely.