Friday, November 2, 2007

Simple Arithmetic in the Bourne Shell


Most folks use shells like bash and ksh (myself included) because of the additional functionality they provide. Shells like sh, jsh, ash and the standard posix are more limited and don't come with a lot of bells and whistles.

Of course, working in a limited shell does have its advantages. For instance, if you write a script in sh, it'll probably work on most any system you port it to. Write in on Solaris and you can most likely run it on Solaris, HP-UX, SCO, Linux, etc.

One of the bonuses the more advanced shells come with is the ability to perform arithmetic simply. However, simply because the functionality exists overtly in the more advanced shells doesn't mean that, without a little practice, you can't perform arithmetic just as easily in "lesser" shells.

In sh (which we'll use as our example "simple" shell from this point forward) you can do arithmetic pretty easily if you know how to use the "expr" command.

Let's say you want to add 2 + 2 and assign that result to a variable. Simple enough, right? In ksh you could simply do:

let result=$a+$a
echo $result

And you're all set. Of course, it's not that much more difficult in sh. As shown below:

result=`expr $a + $a`
echo $result

Doesn't seem all that much more difficult, huh?

Basically, in sh you have to use expr. That's okay, because its on virtually every flavor of Unix available, as is sh. You get your result from expr (which simply evaluates expressions; arithmetic and otherwise) by calling it from between the backticks (``). Backticks in Unix are just a simple way of saying "replace what's within these backticks with the result of the expression, calculation, function or assignment executed within these backticks."

So, to break it down, sh simply does this:

result=`expr 2 + 2`
expr 2 + 2 returns 4

There are lots of things you can do like this in lesser shells. Ultimately, it's a user preference, but, if you're looking for maximum portability, taking advantage of the lesser shells is a great way to go. Virtually everything that can be done easily in more user-friendly shells can be done in lesser shells.

Sometimes it's simple, like this, and sometimes its beyond the point of confusing. For instance, faking arrays in sh isn't very complicated, but it can be very easy to lose track of. But that's for another day!

, Mike