Creating complex commands on the command-line can be challenging the first time, but is worth the invested effort. One aid that assists in creating complex commands is loops. Using loops, you can take often-used commands that would normally be executed in sequence manually, and have them done automatically. This is perhaps one of the most useful features in command-line usage other than perhaps piping output from one command as input to another, or redirecting output of commands.

The use of loops and if/else statements will be familiar to anyone who has done any kind of programming. And while these loops can be used in shell scripts, they can also be used on the command-line itself. For instance, often I find myself executing the same command over again, but with a slight variation in arguments. Instead of executing the command once, hitting the up arrow when it’s completed, and changing one option, this can be automated to execute any number of commands in a row. It can also take advantage of using the output of other commands as input to constructing the loop.

For example, if you need to execute the same script with a varying argument, you could use:

$ for i in i586 x86_64; do seciurt 2008.1 $i foo.src.rpm; done

This command will call the seciurt script twice, the first time as seciurt 2008.1 i586 foo.src.rpm and the second time as seciurt 2008.1 x86_64 foo.src.rpm. In an instance where two arguments need to be changed in a logical format (i.e., calling seciurt to rebuild a src.rpm file for multiple distributions with the same two supported architectures), you would use:

$ for x in 2008.1 2008.0 2007.1; do for i in i586 x86_64; do seciurt $x $i foo-1.0-${x}.src.rpm; done; done

This calls seciurt six times; the first time would be as seciurt 2008.1 i586 foo-1.0-2008.1.src.rpm and the last time as seciurt 2007.1 x86_64 foo-1.0-2007.1.src.rpm. You will note that the variable $x is used two ways: $x and ${x}. The second is required to be called in that manner because there is no whitespace surrounding it and as such will match foo-1.0- instead of foo-1.0-2007.1.src.rpm, which can be seen by executing the following test:

$ touch foo1foo
$ x=1; ls foo$xfoo
ls: cannot access foo: No such file or directory
$ x=1; ls foo${x}foo

Remembering this “escaping” of variables can make for some very interesting CLI commands. The ability to nest loops within loops can also make things interesting with a little bit of creativity. Finally, you can use the output of other commands as input for the loop:

$ touch 1 2 3
$ for i in $(ls *); do echo $i; done

Here you can see the output of the ls command is used as arguments to the for loop.

Get the PDF version of this tip here.

Vincent Danen is the Security Team Manager for Mandriva and lives in Canada. He has been writing about and developing on Linux for over 10 years.

Delivered each Tuesday, TechRepublic’s free Linux and Open Source newsletter provides tips, articles, and other resources to help you hone your Linux skills. Automatically sign up today!