For Loops
Do something 100 times. Process every file in a directory. Iterate over a list. That's what for loops do.
Basic For Loop
hljs bash
#!/bin/bash
for name in Alice Bob Charlie; do
echo "Hello, $name!"
done
Terminal
$./greet.sh
Hello, Alice!
Hello, Bob!
Hello, Charlie!
Loop Over Files
hljs bash
#!/bin/bash
for file in *.txt; do
echo "Processing: $file"
done
Terminal
$./process.sh
Processing: file1.txt
Processing: file2.txt
Processing: notes.txt
No Matches?
If no .txt files exist, *.txt doesn't expand and the loop runs once with literal *.txt. Check for this:
hljs bash
for file in *.txt; do
[[ -f "$file" ]] || continue
echo "$file"
done
Loop Over Command Output
hljs bash
#!/bin/bash
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "User: $user"
done
Or better:
hljs bash
#!/bin/bash
for dir in $(ls /var/log); do
echo "Log directory: $dir"
done
Range of Numbers
hljs bash
#!/bin/bash
# Using brace expansion
for i in {1..5}; do
echo "Number: $i"
done
Terminal
$./count.sh
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
With Step
hljs bash
# Count by 2s
for i in {0..10..2}; do
echo "$i"
done
# Output: 0 2 4 6 8 10
# Count backwards
for i in {5..1}; do
echo "$i"
done
# Output: 5 4 3 2 1
C-Style For Loop
hljs bash
#!/bin/bash
for (( i=0; i<5; i++ )); do
echo "Index: $i"
done
Terminal
$./index.sh
Index: 0
Index: 1
Index: 2
Index: 3
Index: 4
Useful when you need:
- Custom start/end
- Custom increment
- Access to the counter
Loop Control
Skip Iteration: continue
hljs bash
#!/bin/bash
for i in {1..5}; do
if [[ $i -eq 3 ]]; then
continue # skip 3
fi
echo "$i"
done
# Output: 1 2 4 5
Exit Loop: break
hljs bash
#!/bin/bash
for file in *.log; do
if [[ "$file" == "error.log" ]]; then
echo "Found error.log, stopping"
break
fi
done
Practical Examples
Batch Rename Files
hljs bash
#!/bin/bash
# Add prefix to all .txt files
for file in *.txt; do
mv "$file" "backup_$file"
done
Process Multiple Servers
hljs bash
#!/bin/bash
servers="web1 web2 web3 db1"
for server in $servers; do
echo "Checking $server..."
ping -c 1 "$server" > /dev/null && echo " UP" || echo " DOWN"
done
Create Multiple Directories
hljs bash
#!/bin/bash
for month in {01..12}; do
mkdir -p "reports/2025/$month"
done
Backup Multiple Databases
hljs bash
#!/bin/bash
databases="users products orders"
for db in $databases; do
echo "Backing up $db..."
mysqldump "$db" > "${db}_backup.sql"
done
Knowledge Check
What does {1..5..2} expand to?
Quick Reference
| Syntax | Purpose |
|---|---|
for x in a b c | Loop over list |
for f in *.txt | Loop over files |
for i in {1..10} | Loop over range |
for i in {0..10..2} | Range with step |
for ((i=0;i<n;i++)) | C-style loop |
continue | Skip to next iteration |
break | Exit loop early |
Key Takeaways
for var in list; do ... doneis the basic structure- Glob patterns like
*.txtiterate over matching files {1..10}creates number ranges{1..10..2}adds a step- C-style loops
(( ))for complex counters continueskips,breakexits- Always quote
"$var"in loops
Next: while loops for conditional repetition.