Contents:
Beyond the Basics
The Story of : # #!
Don't Need a Shell for Your Script? Don't Use One
Fun with #!
A File That Shows Itself... and What #! Does
Making Sure Your Script Runs with Bourne Shell, Without #!
The exec Command
Handling Signals to Child Processes
The Unappreciated Bourne Shell ":" Operator
Removing a File Once It's Opened - for Security and Easy Cleanup
The Multipurpose jot Command
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
Handling Files Line-by-Line
The Ins and Outs of Redirected I/O Loops
A Shell Can Read a Script from its Standard Input, But...
Shell Scripts On-the-Fly from Standard Input
Quoted hereis Document Terminators: sh vs. 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
A Better read Command: grabchars
Testing Two Strings with One case Statement
Arrays in the Bourne Shell
Using a Control Character in a Script
Shell Lockfile
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 (see article
44.4),
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, article
45.2,
explains how #!
started.
Article
45.3
explains that your "shell scripts" may not need a shell at all.
Article
45.4
will give you a few grins as it shows unusual examples of #!
-and
article
45.5
has experiments to help you understand what #!
does.
If your UNIX doesn't have #!
, the trick in article
45.6
will let you be sure your scripts run with the Bourne shell.
Scripts using an interpreter that isn't a shell are in articles 25.11, 25.12, and 35.8.
The next five articles are about processes and commands.
The exec command, article
45.7,
replaces the shell with another process; it can also be used to change
input/output redirection (see below).
The trap command can control how signals are passed to child processes;
see article
45.8.
The :
(colon) operator evaluates its arguments and returns a
zero status - article
45.9
explains why you should care.
UNIX keeps a file on-disk once it's been opened; as article
45.10
explains, this has its ups and downs.
The jot command, article
45.11,
is useful for all kinds of operations with lists of numbers and characters.
Next are techniques for handling variables and parameters.
Parameter substitution, explained in article
45.12,
is a compact way to test, set, and give default values for variables.
You can use the $0
parameter
and UNIX links to make the same script
have multiple names and do multiple things; see article
45.13.
Article
45.14
shows the easy way to get the last command-line argument.
Article
45.15
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. Article 45.16 shows how to make the for loop read from standard input. Article 45.17 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 article 45.18. A while loop can have more than one command line at the start; see article 45.19.
Next is an assortment of articles about input/output. Article 45.20 introduces open files and file descriptors - there's more to know about standard input/output/error than you might have realized! Article 45.21 has a look at file descriptor handling in the Bourne shell, swapping standard output and standard error. The shell can redirect the I/O from all commands in a loop at once; article 45.22 explains one use for this technique and article 45.23 explains good and bad points of doing this.
The shell can read commands directly from a shell script file. As article 45.24 points out, a shell can also read commands from its standard input, but that can cause some problems. Article 45.25 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; article 45.26 explains. Article 45.27 shows how to turn off echoing while your script reads a "secret" answer such as a password.
Three articles- 45.28, 45.29, and 45.30- show uses for the versatile expr expression-handling command. Article 45.31. covers multiple command substitution (9.16). The grabchars program in article 45.32 is similar to read (44.13)- but grabchars doesn't need a RETURN after the answer; grabchars also can prompt and do basic tests on the answer.
Article 45.33 shows a trick for making one case statement (44.5) test two things at once. Article 45.34 has a trick for simulating arrays in the Bourne Shell. Article 45.35 uses echo and tr to get a control character in a script without typing the literal character into the file. Finally, article 45.36 has a simple technique for getting exclusive access to a file or other system resource.
-