Bash For Loops

Looping in a Bash Script

Page content

I run into a a bunch of situation where I have to loop over outputs from cli outputs in Bash scripts. I can never remember where to find this information, so I’ll document it here.

This is just an example of what I typically need to do:

Using read in a for loop

Get a long running command output, for this example, I’ll just use the output from a find command:

CPP_FILES = (find . -name *.cpp)

The list of files stored in $CPP_FILES now needs to be iteratated over.

while IFS= read -r file; do
  # Perform actions on each file
  echo "$file"
done <<< "$CPP_FILES"

In this example, the find command is used to generate a newline-separated list of .cpp files, which is stored in the CPP_FILES variable. The while loop reads each line from the CPP_FILES variable using read, and the actions to be performed on each file are placed inside the loop.

Remember to replace the echo "$file" line with your desired actions for each file.

Using for loop with a range

You can use a for loop to iterate over a range of numbers in Bash. Here’s an example:

for i in {1..5}; do
  echo "Number: $i"
done

In this example, the for loop iterates over the numbers 1 to 5. The variable i takes the value of each number in the range, and the actions to be performed on each iteration are placed inside the loop. In this case, we simply echo the value of i. Note that in order to do this you have to be on Bash 3.0+, which was released in 2004. So a really old (unpatched) server or embedded system might have this problem.

This can also be done with a sequence:

for i in $(seq 1 5); do
  echo "Number: $i"
done

Similarly, you can do this with an increment operator:

for ((i = 1 ; i < 6 ; i++ )); do
  echo "Number: $i"
done

This last one I’m always a little worried about as the readability is not the clearest to understand since you have an off-by-1 issue.

Using for loop with an array

You can also use a for loop to iterate over an array in Bash. Here’s an example:

fruits=("apple" "banana" "orange")

for fruit in "${fruits[@]}"; do
  echo "Fruit: $fruit"
done

In this example, the for loop iterates over each element in the fruits array. The variable fruit takes the value of each element, and the actions to be performed on each iteration are placed inside the loop. In this case, we echo the value of fruit.

Using for loop with command substitution

You can use command substitution to generate a list of items and iterate over them using a for loop. Here’s an example:

for file in $(ls *.txt); do
  echo "File: $file"
done

In this example, the for loop iterates over the files with a .txt extension in the current directory. The $(ls *.txt) command substitution generates the list of files, and the variable file takes the value of each file in the list. The actions to be performed on each iteration are placed inside the loop, and in this case, we echo the value of file.