## 1.8. Anyone Can Program the Shell

One of the really wonderful things about the shell is that it doesn't just read and execute the commands you type at a prompt. The shell is a complete programming language.

The ease of shell programming is one of the real highlights of Unix for novices. A shell program need be no more than a single complex command line saved in a file -- or a series of commands.

For example, let's say that you occasionally need to convert a Macintosh Microsoft Word file for use on your Unix system. Word lets you save the file in ASCII format. But there's a catch: the Mac uses a carriage return ASCII character 015 to mark the end of each line, while Unix uses a linefeed (ASCII 012). As a result, with Unix, the file looks like one long paragraph, with no end in sight.

That's easy to fix: the Unix tr (Section 21.11) command can convert every occurrence of one character in a file to another:

>     bash-2.04$ tr '\015' '\012' < file.mac > file.unix

But you're a novice, and you don't want to remember this particular piece of magic. Fine. Save the first part of this command line in a file called mac2unix in your personal bin directory (Section 7.4):

>     tr '\015' '\012'

Make the file executable with chmod (Section 50.5):

>     bash-2.04$ chmod +x mac2unix

Now you can say:

>     bash-2.04$ mac2unix < file.mac > file.unix

But why settle for that? What if you want to convert a bunch of files at once? Easy. The shell includes a general way of referring to arguments passed to a script and a number of looping constructs. The script:

`for` Section 35.21, `$x` Section 35.9

>     for x
>     do
>         echo "Converting $x"
>         tr '\015' '\012' < "$x" > "tmp.$x"
>         mv "tmp.$x" "$x"
>     done

will convert any number of files with one command, replacing each original with the converted version:

>     bash-2.04$ mac2unix file1 file2 file3 ...

As you become more familiar with Unix, it quickly becomes apparent that doing just a little homework can save hours of tedium. This script incorporates only two simple programming constructs: the for loop and variable substitution (Section 35.9, Section 35.3).[1] As a new user with no programming experience, I learned these two constructs by example: I saved a skeleton for loop in a file and simply filled in the blanks with whatever commands I wanted to repeat. Section 35.2 has more about shell programming.

> [1][Tim is keeping this article simple, as an illustration of how easy writing a shell program can be. If you're writing this little script for general use, you can make it work like a filter (Section 1.5) by adding four or five more lines of code: a case (Section 35.10) or if (Section 35.13) statement that tests the number of command-line arguments. With no filename arguments, the script would simply run `tr '\015' '\012'`. -- JP]

In short, Unix is sometimes difficult because it is so rich and complex. The user who doesn't want to learn the complexity doesn't have to -- the basic housekeeping commands are simple and straightforward. But the user who wants to take the time to investigate the possibilities can uncover a wealth of useful tools.

-- TOR

Copyright © 2003 O'Reilly & Associates. All rights reserved.