The bash for loop is a powerful tool for automating tasks in Linux and other Unix-based systems. As a beginner, understanding how to use for loops can open up new possibilities for writing scripts that are productive, efficient, and useful.
In this comprehensive guide, we will walk through bash for loop basics, provide a variety of examples ranging from 1 to 10, and explain how to customize your loops for advanced scenarios. By the end, you will have the skill and confidence to start using for loops for everything from basic tasks like printing sequences to more complex programming challenges. Let‘s get started!
Bash For Loop Fundamentals
The basic syntax for a bash for loop is:
for variable in list; do
commands
done
This structure allows you to iterate through a list of items and perform commands on each item in the list. Here is a quick overview of what each part does:
-
for variable
: This sets up the variable that will represent the current item in the list during each iteration. The variable can be named anything but num and i are common choices. -
in list
: This specifies the list of items to iterate through. This could be a sequence of numbers, array of strings, list of files, etc. -
do commands
: The commands here will execute on every item in the list sequentially. This block handles all the main work. -
done
: Signals the end of the for loop block.
You‘ll also commonly see additional statements like (( i++ ))
to increment a counter variable, enabling even more programming logic.
Now, let‘s see some examples of how to create bash for loops both simple and complex.
Bash For Loop Examples from 1 to 10
Let‘s start exploring the bash for loop by printing the numbers 1 through 10. This is a great beginner-friendly example.
1. Traditional For Loop with Numeric Sequence
The most straightforward way is by using a numeric sequence.
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10; do
echo "Number: $i"
done
This loop will print each number in sequence successfully:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Number: 6
Number: 7
Number: 8
Number: 9
Number: 10
By manually enumerating the numbers, we were able to print an incremental count. Note that the numbers themselves had to be statically coded. Next, we‘ll avoid that redundancy by using variables.
2. Incrementing Variable For Counting Loop
Instead of explicitly listing the numbers like above, we can rely on variables to dynamically track the count in an incrementing loop:
#!/bin/bash
start=1
end=10
for (( i=start; i<=end; i++ )); do
echo "Number: $i"
done
This loop prints the same 1 through 10 sequence but has a couple advantages:
- No need to manually type all numbers
- Can easily configure range by setting start and end values
- More flexibility for incrementing logic using variables
3. Using Brace Expansion For Sequence Range
Brace expansion is another technique that generates a sequence without any complex math:
for i in {1..10}; do
echo "Number: $i"
done
The {1..10}
syntax produces the incremental number list automatically. When bash processes this, it maps to 1 2 3 4 5 6 7 8 9 10
before running. So the loop output is identical.
This approach streamlines sequence generation cleanly right inside the for statement.
4. Reading Numbers from External File
Hard-coding numbers works for simplicity, but isn‘t very practical. For dynamic data, read from an external source file instead.
numbers.txt contents:
1
2
3
4
5
6
7
8
9
10
Now loop through numbers.txt to echo its contents:
for i in $(cat numbers.txt); do
echo "Number: $i"
done
This gives the same output as before, demonstrating how to load dynamic content from files.
You could store hundreds of numbers across various files, retrieving what you need programmatically for a given for loop without changes.
5. Output Numbers to a File
We‘ve printed numbers to the terminal. But what about writing to a file instead?
for i in {1..10}; do
echo $i >> numbers.txt
done
Using >>
append redirect after the loop body, we can save the output to numbers.txt:
1
2
3
4
5
6
7
8
9
10
Now you have a reusable numbers file generated automatically!
6. Sum Values from Sequence
Extend the for loop with math to calculate a total for all numbers:
sum=0
for i in {1..10}; do
echo $i
sum=$((sum + i))
done
echo "Sum: $sum"
By adding each number to the running $sum variable, we can display the final total after the loop concludes:
1
2
3
4
5
6
7
8
9
10
Sum: 55
This demonstrates how a for loop can perform a calculation across any range of numbers.
7. Custom Step Values
The examples above increment numbers by 1 automatically. To set a custom step value, we introduce a third expression:
for((i=1; i<=10; i=i+2)); do
echo $i;
done
Now this will count by 2‘s:
1
3
5
7
9
The middle i<=10
sets the limit, while i=i+2
makes the +2 step happen.
You can combine this with brace expansion too:
for i in {1..10..3}; do
echo $i
done
Prints:
1
4
7
10
This adds a third parameter after the range to specify a step of 3.
8. Loop Through Command Line Arguments
Instead of hard-coded strings, you can directly loop through arguments passed when the script was called:
testloop.sh contents:
for i in "$@"; do
echo $i
done
Now when invoking the script:
bash testloop.sh First Second Third
Prints each word on its own line:
First
Second
Third
The unexpanded $@
contains all CLI arguments as separate items for convenient iteration.
9. Read Lines of External File
A common task is processing an external file line-by-line. The easiest way is using a while
read loop, but this can be combined with a for loop too:
for i in $(cat testfile.txt); do
echo "Line: $i"
done
testfile.txt contents:
First line
Second line
Last line
Loop output:
Line: First line
Line: Second line
Line: Last line
This clearly prints each line separately after the for loop splits them appropriately.
10. Infinite Loop with Conditional Break
Be careful to avoid infinite loops! But we can also construct one intentionally by omitting the increment logic:
count=1
for (( ; ; )); do
if [ $count -gt 5 ]; then
break
fi
echo $count
count=$((count + 1))
done
The for (( ; ; ))
essentially acts as a while true
since no exit expression gets evaluated.
We print and increment $count continually…until hitting the break
once a threshold is passed.
This outputs:
1
2
3
4
5
And then terminates properly due to break
.
Having an explicit exit condition prevents any issues!
Customizing Advanced For Loops
By now, you should feel comfortable using bash for loops for basic scripts. But we can extend these skills even further to handle advanced, real-world shell programming scenarios you may encounter.
Check out some additional examples below for creative ways to customize loop behavior.
Nest Multiple For Loops
Need multiple inner and outer iterative processes depending on your goal? Nest for loops!
for (( i=1; i<=3; i++ )); do
echo "Outer loop: $i"
for (( j=1; j<=2; j++ )); do
echo "Inner loop: $j"
done
done
Prints:
Outer loop: 1
Inner loop: 1
Inner loop: 2
Outer loop: 2
Inner loop: 1
Inner loop: 2
Outer loop: 3
Inner loop: 1
Inner loop: 2
The outer loop runs fully to completion for EACH iteration of the inner loop.
Loop Through Array Elements
Arrays store multiple string values. Loop through each element by index position:
arr=("first" "second" "third")
for i in "${arr[@]}"; do
echo $i
done
Prints each array value on its own line:
first
second
third
Make sure to use ${arr[@]}
to retrieve all elements.
Read Directories Recursively
If working with filepaths, recursive loops greatly help process subdirectories.
This example walks an entire tree:
for dir in /path/*/; do
echo "In directory: $dir"
for file in "$dir"/*; do
echo "- File: $file"
done
done
The outer loop handles the high-level directories while the inner loop prints the individual files.
This can scan arbitrarily large filesystem subtrees.
Loop Control with Statuses
We used break
before for early termination. Two other important commands are continue
and exit
.
These allow skipping iterations or stopping the script entirely from within running loops when needed.
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue
fi
echo "Number: $i"
if [ $i -eq 8 ]; then
exit
fi
done
Prints:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 6
Number: 7
The continue
made it skip 5, while exit
stopped after hitting 8.
Having control constructs makes loops far more useful.
Conclusion
Learning to properly leverage Bash for loops provides amazing scripting capabilities. Whether needing to iterate a fixed number of times, process dynamic sets of files, parse command line arguments, or handle recursion, using for loops unlocks it all!
We first covered core syntax and basics with simple examples counting from 1 to 10. Later, more advanced customizations helped tackle real-world programming challenges. From arithmetic to control flow, files/text parsing, directories, strings and arrays, for loops have nearly unlimited use cases.
I challenge you to start applying these for loop best practices in your own Bash shell scripting workflow today. Look for opportunities to replace mundane, repetitive tasks with automated loops. And explore nesting or chaining several together to achieve next-level Linux process automation!
Let me know in the comments about your favorite tips for maximizing for loops. Thanks for reading and happy scripting!