Bash For Loop: Syntax and Examples
Updated on
•6 min read

Loops are a fundamental concept in programming languages. They allow you to execute a series of commands repeatedly until a specific condition is met.
In scripting languages like Bash, loops are especially useful for automating repetitive tasks, eliminating the need to duplicate the code.
There are three basic loop constructs in Bash scripting: for loop, while loop
, and until loop
.
This guide focuses on the for loop in Bash, including its syntax variations, nesting, flow-control statements like break and continue, and practical examples.
The Standard Bash for Loop
The for loop iterates over a list of items and performs the given set of commands.
The basic Bash for loop syntax is:
for item in [LIST]
do
[COMMANDS]
done
The [LIST] can be a series of strings separated by spaces, a range of numbers, command output, an array, command-line arguments, and so on.
Loop over strings
The example below shows a loop that iterates over a list of strings. The loop operates on each item in the list, and the variable element stores the item that the loop is currently operating on.
for element in Hydrogen Helium Lithium Beryllium
do
echo "Element: $element"
done
The loop will produce the following output:
Element: Hydrogen
Element: Helium
Element: Lithium
Element: Beryllium
Loop over a range
You can use the sequence expression to specify a range of numbers or characters by defining the start and the end point of the range. The sequence expression takes the following form:
{START..END}
Here is an example loop that iterates through all numbers from 0 to 3:
for i in {0..3}
do
echo "Number: $i"
done
Number: 0
Number: 1
Number: 2
Number: 3
Starting from Bash 4, you can also specify an increment when using ranges:
{START..END..INCREMENT}
Here’s an example showing how to increment by 5:
for i in {0..20..5}
do
echo "Number: $i"
done
Number: 0
Number: 5
Number: 10
Number: 15
Number: 20
Loop over array elements
You can use the for loop to iterate over an array of elements.
In the example below, we define an array named BOOKS and iterate over each element of the array.
BOOKS=('In Search of Lost Time' 'Don Quixote' 'Ulysses' 'The Great Gatsby')
for book in "${BOOKS[@]}"; do
echo "Book: $book"
done
Book: In Search of Lost Time
Book: Don Quixote
Book: Ulysses
Book: The Great Gatsby
The C-style for loop
Bash for loop also supports a C-like syntax:
for ((INITIALIZATION; TEST; STEP))
do
[COMMANDS]
done
The INITIALIZATION part is executed only once when the loop starts. Then, the TEST part is evaluated. If it is false, the loop is terminated. If the TEST is true, commands inside the body of the for loop are executed, and the STEP part is updated.
In the following example code, the loop starts by initializing i = 0 and, before each iteration, checks whether i ≤ 10. If true, it prints
the current value of i and increments the variable i by 1 (i++). Otherwise, the loop terminates.
for ((i = 0 ; i <= 1000 ; i++)); do
echo "Counter: $i"
done
The loop will iterate 1001 times and produce the following output:
Counter: 0
Counter: 1
Counter: 2
...
Counter: 998
Counter: 999
Counter: 1000
Nested Loops
A nested loop is a loop inside another loop. You can nest any loop any number of times.
In a nested for loop, the inner loop runs a complete cycle of its iterations for every outer loop iteration. This means that for every execution of the outer loop, the inner loop will execute all of its iterations until the outer loop completes its cycle.
Here’s an example code that copies three files one by one to three servers.
for f in file_{1..3}; do
for j in server_{1..3}; do
echo "Copying file $f to server $j";
# command to copy files
done;
done
Copying file file_1 to server server_1
Copying file file_1 to server server_2
Copying file file_1 to server server_3
Copying file file_2 to server server_1
Copying file file_2 to server server_2
Copying file file_2 to server server_3
Copying file file_3 to server server_1
Copying file file_3 to server server_2
Copying file file_3 to server server_3
Controlling Loop Flow: break and continue Statements
The break and continue statements
are used to control the for loop execution.
break – terminate the loop entirely
The break statement terminates the current loop and passes program control to the statement that follows the terminated statement. It is generally used to terminate the loop when a specific condition is met.
In the following example, we use the if statement
to terminate the execution of the loop once the current iterated item is equal to ‘Lithium’.
for element in Hydrogen Helium Lithium Beryllium; do
if [[ "$element" == 'Lithium' ]]; then
break
fi
echo "Element: $element"
done
echo 'All Done!'
Element: Hydrogen
Element: Helium
All Done!
continue – skip to the next iteration
The continue statement exits the current iteration of a loop and passes program control to the next iteration of the loop.
In the following example, we iterate through a range of numbers. When the current iterated item is equal to ‘2’, the continue statement will cause execution to return to the beginning of the loop and to continue with the next iteration:
for i in {1..5}; do
if [[ "$i" == '2' ]]; then
continue
fi
echo "Number: $i"
done
Number: 1
Number: 3
Number: 4
Number: 5
Real-World Examples
Renaming files with spaces in the filename
The following example shows how to rename all of the files in the current directory with a space in their names by replacing the spaces with underscores:
for file in *\ *; do mv "$file" "${file// /_}" doneLet’s break down the code line by line:
- The first line creates a
forloop that iterates over a list of all files with a space in their names. (The expression*\ *creates the list). - The second line applies to each item in the list and renames the file, replacing spaces with underscores (
_). The part${file// /_}is using the shell parameter expansion to replace a pattern within a parameter with a string. doneindicates the end of the loop segment.
- The first line creates a
Changing file extension
The following example shows how to use a Bash
forloop to rename all files ending with .jpeg in the current directory, replacing the file extension from ‘.jpeg’ to ‘.jpg’.for file in *.jpeg; do mv -- "$file" "${file%.jpeg}.jpg" doneLet’s analyze the code line by line:
- The first line creates a
forloop that iterates through a list of all files ending in ‘.jpeg’. - The second line applies to each item in the list and moves the file to a new one, replacing ‘.jpeg’ with ‘.jpg’. The expression
${file%.jpeg}removes the ‘.jpeg’ part from the filename using the shell parameter expansion doneindicates the end of the loop segment.
- The first line creates a
Restart multiple Docker containers
Here is an example that can be useful after deploying new code and you want to restart more than one container:
for container in web db cache redis; do docker restart "$container" && echo "Restarted $container" doneContainers are passed to the loop as a list of strings.
Conclusion
The Bash for loop is used to execute a given set of commands repeatedly for a fixed number of times. Combined with break, continue, nesting, and parameter expansion, it enables elegant solutions to many automation tasks.
Mastering for loops will significantly boost your Bash scripting skills. Happy scripting!


