Linux For Loop

By | 2023-10-14

I chose this topic because SEO tools found it is a common search topic. The answer you need is there are multiple variants of Linux for loops. The technically correct answer is there isn’t such a thing, as Linux is just a kernel. The answer you want is how to use a Linux for loop. For the sake of simplicity, I am assuming you mean using a command line shell.

The syntax, or what you need to type to use a for loop depend on your shell. There multiple shells that all have their features and quirks. As for for loops, there are two main variants, csh and Bourne compatible. The most popular is probably bash. The bash shell is one of many shells that are called Bourne compatible. This means if you write a script or run a command for the Bourne shell, a Bourne compatible shell well run it with no issues. You may encounter the term POSIX or sh shell compatible. I’ll spare you the details, but any shell that is Bourne, POSIX, or sh compatible will use the same syntax with for loops. If you aren’t sure, try the Bourne compatible variant first.

Bourne compatible

There are a few ways you can do it, even as a one-liner, but multi-line is easier to read and understand. Below is a simple example you can copy and paste into a terminal:

for num in 1 2 3
do
echo $num is a nice number
echo $num is a good number
done

You start with the for keyword. Follow it with a name of a variable you wish to assign the values to. Follow that with a list of items you want to iterate through. Then press enter for a new line. Then type the command or commands you wish to run, one on each line. Finally, type done. Press enter and your loop will run.

When you press enter after each line, you may see some character appear at the beginning of it, most likely a >. This is to be expected. It just means it is a continuation of a command started on a previous line. Ignore it and continue following the examples and it should work just fine. I’ll provide some real world examples at the end of this guide so you know what to expect.

When you enter the command(s) you wish to run, use the variable name you chose on the first line, preceded by a $, in the place you would use a typical argument. E.g.

rm oldfile1

Becomes:

rm $loopvar

csh variants

This is a bit different than the previous variant. Here is an example:

foreach num ( 1 2 3 )
echo $num is great 
echo $num is a number
end

As with the Bourne version, you may see a character at the beginning of each new line, most likely a ?. As with the previous variant, you can safely ignore it. It just means it is a continuation of a command started on a previous line. Notice how instead of for, you use foreach. Leave out the word in when using csh. Simply follow foreach with the variable name. The items you wish to iterate through must be enclosed in (). Also notice that the do keyword is left out and instead of done, the loop specification is finished with the keyword end.

One Liners

You can put entire loops on one line if you like. Just replace where new lines would be, except after do with a ;.

Bourne variant:

for n in 1 2 3; do echo $n; done

Just separate commands with ; for multiple commands per iteration.

for n in 1 2 3; do echo $n; echo "$n is a number"; done

Unfortunately, there is no straightforward way to do it with csh. There are ways it can be done, but aren’t worth the effort in my opinion.

Real Examples

The example below loops through all the hosts in the file /tmp/hosts and pings them. Notice how the type of white space doesn’t matter. Some hosts are on lines by themselves, some are separated by spaces.

$ for host in $(cat /tmp/hosts)
> do
> fping $host
> done
192.168.1.20 is alive
192.168.1.244 is alive
192.168.1.240 is alive
192.168.1.241 is alive
192.168.1.125 is unreachable
192.168.1.251 is unreachable
$ cat /tmp/hosts
192.168.1.20 192.168.1.244 192.168.1.240 192.168.1.241 
192.168.1.125
192.168.1.251

In the above example, I am using the bash shell and using command substitution to populate the list of items to loop through. Some shells use back quotes ` for their command substitution syntax. Below is the same loop using csh, which uses `:

% foreach host  (`cat /tmp/hosts`) 
? fping $host
? end
192.168.1.20 is alive
192.168.1.244 is alive
192.168.1.240 is alive
192.168.1.241 is alive
192.168.1.125 is unreachable
192.168.1.251 is unreachable

References