An essential rule of system administration: If you need to do something often, try to write a script to do it for you. If you need to do something several times within a script, you’ll need to be able to use loop statements to repeat something until done. With GNU Bash, you’ll do this with for
, while
, and until
statements.
If you’ve done any programming, you’re probably familiar with these statements already. If you’re like me, and were introduced to bash
scripting without benefit of a programming background, they might not be quite so obvious. Let’s start by explaining the differences between the statements, and then move on to examples.
The for
loop is used to iterate through an action until done. Let’s say you have a directory full of images that you want to convert from one format to another. You could use a for
loop and ImageMagick’s convert
(or another program) to convert JPEG images into PNG format, for instance. Or create a script to take a directory full of MP3s or WAV files and convert to Ogg Vorbis.
The while
loop is used to perform an action while a condition is true, and until
does the opposite — it performs an action until a condition is true. So you might run a counter, for example, up to 10 and perform an action until the counter hits 10. We’ll look at this more closely in the examples.
Using for
Loops
Let’s start with the for
loop. The syntax is:
for i in $( command ); do command $i; done
That’s on the command line. If you’re doing a script, you’d format it as:
#!/bin/bash
for i in $( command ); do
command $i
done
So, if I wanted to make a backup copy of all the HTML files in a directory, I’d use:
for i in $( ls *html ); do cp $i $i.bak; done
So set up a variable (i), and then set up the command that will give the loop something to iterate over (ls *html
). Next, do
the action cp
to the files that ls *html
returns, one at a time.
You might be wondering, does the variable have to be i
? Nope. It could any valid variable name. If you want to write a more readable script, you can give it a name like input
or html
.
Here’s a quick tip while you get started: Use echo
to replace the command you wish to run as a test-run. For instance, if you’re iterating through a directory and performing an operation on files, use echo
to give the name of the files the first time through. That way you’ll see that the script is performing as intended, and if not echo
is non-destructive so there’s no harm, no foul if it doesn’t do what you meant to do. Then you can do the real action without fear.
Using while
and until
Next up, we’ll take while
and until
for a test drive. We’re also going to use some Bash conditionals. These are used to evaluate an expression like “is a variable larger or smaller than X?” or “does a this file exist, and is it a directory?” You might want to use a conditional to ensure that a file exists and is readable, or to ensure that a file exists and has its set group ID (sgid) bit set.
Let’s do something simple, and create some empty files. Not very useful, but a good example. Here we go:
i=0
while [ $i -lt 22 ]
do
touch $i
i=$[$i+1]
done
This will create file name 0 through 21. Remember, it’s while the variable is less than (-lt
) 22, so it starts at zero and stops at 21.
Now let’s get rid of those file by changing the script around with a until
statement:
i=0 until [ $i -eq 22 ] do rm $i i=$[$i+1] done
All we’ve had to do here is flip while
to until
, and change the conditional to equal (-eq
) so that the until loop runs until the variable is equal to 22. Instead of touch
ing a file, we’re removing the files. Easy, right?
In the next installment, we’ll look at conditionals in more detail, and using them with the for
, while
, and until
loops to do some standard system administration tasks. Until then, try these out on your machine and see what you can do to automate your work on Linux!