In this, my first column, I thought it would be a good idea to get you into the idea of using shell scripts. Shell scripts are essential to the productive use of a UNIX OS. We’ll concentrate on /bin/csh, the UNIX C-shell interpreter that’s the choice of most everyday users, including system admins when they’re not required to use Bourne-shell system scripts.
Let’s start with a simple tool. To define some commands, we have to define some aliases. An alias is a csh method of defining reusable commands. Let’s take a trivial example:
alias lsc ls –C
We have defined a new command called lsc, which, when typed in a csh window, will perform a multicolumn file listing of the current working directory. Type it in your csh window and try it. The syntax of alias is:
alias new-command-name command string
Here’s another set of useful commands:
alias up cd ..
alias Up cd ../../
alias UP cd ../../../
These commands allow you to traverse the directory tree upwards of one, two, and three levels, respectively. These little ditties are useful in typical UNIX file systems, since it seems that information is found in innumerable tree levels. Remember that csh is case sensitive, so all three commands are indeed unique.
Let’s try some one-liners with files. To view the contents of a text file called Junkone page at a time, you can use the string:
cat junk | more
The utility cat will take the contents of Junk and use a pipe [|] to redirect the output to the paging utility more. Let’s generalize this command by making cat work in this way for any text file. Let’s define a new command by typing:
alias seemore ‘cat \!* | more
We have invoked the use of delayed parsing by wrapping the command string in quotes. Normally, the csh parser will attempt to interpret every string element as it goes. (Incidentally, you can take advantage of this behavior to build new commands from aliases you have previously defined.) Inside this quoted string is the use of the pipe designator. The pipe redirects the output from cat in the first part to the standard input of paging utility more. So, we have used a pipe to tie two useful utilities together to do something new. The \!* argument for cat uses the escape character [\] to halt any interpretation of the metacharacter [!]. The sequence !* is a csh shorthand, which allows full argument passing from the executed command line. Now when you type:
you get the same result. If you have a file called Stuff, you issue the command:
and you get a similar response. Simple, elegant.
A little more housekeeping
Using this technique, you can generate new commands on the fly or store them in a file that can be executed whenever you want. Since we’re starting to build up aliases, let’s say you want a way of recounting, one page at a time, the list of aliases you have generated. (See how proficient you are already!) You can do this by typing:
alias | more
To make a new command called am, you type:
alias am ‘alias | more’
When you execute the csh command alias with no arguments, it will recount all of the currently active aliases you have generated. This is fine for a small set of commands, but once you have generated 20 to 30 new commands, you’ll see how useful this housekeeping function is.
Finding loose files
Now back to the file system tools. Let’s say that you know the name of a file in your directory space, but you don’t know the location. We’ll define the command findfile with this code:
alias findfile find ~ “\*\!*\* -print
Here’s a quick breakdown of this string:
- This new command uses the find utility to execute this task.
- The metacharacter [~] is a csh shorthand definition of your home directory.
- Find uses this as the starting point for the file search.
- The –name argument employs a carefully constructed string.
- Double quotes around the argument delay string interpretation.
- The escape character [\] is used to prohibit any interpretation of the wildcard character [*]. So, the first and last part of the string match is a wildcard, which allows a string match on any preceding or succeeding groups of characters (they can also be null).
- The \!* sequence in the middle part uses the escape character [\] to halt any interpretation of the next metacharacter, [!].
- The sequence !* is a shorthand, which we’ve already encountered, that allows full argument passing into your new command findfile. So the string match phrase is *!**, which allows for any string input as an argument to be bracketed by wildcards.
- Finally, the –print option sends the results of the find command to your terminal window. Execution of the command:
will list all instances within your home directory tree of any file with the character string “dunno” in it.
Just the beginning
These few examples should get you started in doing simple csh commands on your own. I’d recommend that you look at your man listings for more syntax information for csh. Execute the command:
to see this information (it should be about 25 pages). On most systems you can use the command:
man –t csh
to print this out to your default printer.
This is enough to chew on for now. In my next column, we’ll concentrate on more complex argument passing into aliased commands. Give yourself a few minutes to try what we have already done, and then go experiment.
Craig Burkhart is a theoretical chemist for The Goodyear Tire & Rubber Company during the day. He holds a B.S. in chemistry, and an M.S. and Ph.D. in polymer physics. He has been hacking shell scripts and programs since the early ‘70s and has played on more computer systems than he can even remember. He does remember his first, though: a PDP-8 with 8 K of real core memory.