# Chapter 36. Shell Programming for the Initiated

#### Contents:

Beyond the Basics
The Story of : # #!
Don't Need a Shell for Your Script? Don't Use One
Making #! Search the PATH
The exec Command
The Unappreciated Bourne Shell ":" Operator
Parameter Substitution
Save Disk Space and Programming: Multiple Names for a Program
Finding the Last Command-Line Argument
How to Unset All Command-Line Parameters
Standard Input to a for Loop
Making a for Loop with Multiple Variables
Using basename and dirname
A while Loop with Several Loop Control Commands
Overview: Open Files and File Descriptors
n>&m: Swap Standard Output and Standard Error
A Shell Can Read a Script from Its Standard Input, but...
Shell Scripts On-the-Fly from Standard Input
Quoted hereis Document Terminators: sh Versus csh
Turn Off echo for "Secret" Answers
Quick Reference: expr
Testing Characters in a String with expr
Grabbing Parts of a String
Nested Command Substitution
Testing Two Strings with One case Statement
Outputting Text to an X Window
Shell Lockfile

## 36.1. Beyond the Basics

This chapter has a bunch of tricks and techniques for programming with the Bourne shell. Some of them are documented but hard to find; others aren't documented at all. Here is a summary of this chapter's articles:

- The first group of articles is about making a file directly executable with #! on the first line. On many versions of Unix, an executable file can start with a first line like this:

  >     #!/path/to/interpreter

  The kernel will start the program named in that line and give it the file to read. Chris Torek's Usenet classic, Section 36.2, explains how `#!` started. Section 36.3 explains that your "shell scripts" may not need a shell at all.

- The next bunch of articles are about processes and commands. The exec command, Section 36.5, replaces the shell with another process; it can also be used to change input/output redirection (see below). The : (colon) operator evaluates its arguments and returns a zero status -- Section 36.6 explains why you should care.

- Next are techniques for handling variables and parameters. Parameter substitution, explained in Section 36.7, is a compact way to test, set, and give default values for variables. You can use the `$0` parameter and Unix links to give the same script multiple names and make it do multiple things; see Section 36.8. Section 36.9 shows the easy way to get the last command-line argument. Section 36.10 has an easy way to remove all the command-line arguments.

- Four articles cover sh loops. A for loop usually reads a list of single arguments into a single shell variable. Section 36.11 shows how to make the for loop read from standard input. Section 36.12 has techniques for making a for loop set more than one variable. The dirname and basename commands can be used to split pathnames with a loop; see Section 36.13. A while loop can have more than one command line at the start; see Section 36.14.

- Next is an assortment of articles about input/output. Section 36.15 introduces open files and file descriptors -- there's more to know about standard input/output/error than you might have realized! Section 36.16 has a look at file-descriptor handling in the Bourne shell, swapping standard output and standard error.

- The shell can read commands directly from a shell script file. As Section 36.17 points out, a shell can also read commands from its standard input, but that can cause some problems. Section 36.18 shows one place scripts from stdin are useful: writing a script that creates another script as it goes.

  Next are two articles about miscellaneous I/O. One gotcha with the here-document operator (for redirecting input from a script file) is that the terminators are different in the Bourne and C shells; Section 36.19 explains. Section 36.20 shows how to turn off echoing while your script reads a "secret" answer such as a password.

- Two articles -- Section 36.22 and Section 36.23 -- show uses for the versatile expr expression-handling command. Section 36.21 is a quick reference to expr. Section 36.24 covers multiple command substitution (Section 28.14).

  Section 36.25 shows a trick for making one case statement (Section 35.10) test two things at once. Finally, Section 36.27 has a simple technique for getting exclusive access to a file or other system resource.

-- JP

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