Shell Developing for the Initiated
Contents:
Beyond the Basics
The Story of : # #!
Don't Need a Shell for Your Script? Don't Use One
Fun with #!
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 Developing: 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
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
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
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
Beyond the Basics
This chapter has a bunch of tricks and techniques for developing 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 ), 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 , explains how
#!
started. Article explains that your "shell scripts" may not need a shell at all. Article will give you a few grins as it shows unusual examples of#!
-and article has experiments to help you understand what#!
does. If your UNIX doesn't have#!
, the trick in article will let you be sure your scripts run with the Bourne shell.Scripts using an interpreter that isn't a shell are in articles , , and .
- The next five articles are about processes and commands. The exec command, article , 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 . 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 explains, this has its ups and downs. The jot command, article , 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 , 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 . Article shows the easy way to get the last command-line argument. Article 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 shows how to make the for loop read from standard input. Article 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 . A while loop can have more than one command line at the start; see article .
- Next is an assortment of articles about input/output. Article introduces open files and file descriptors - there's more to know about standard input/output/error than you might have realized! Article 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 explains one use for this technique and article explains good and bad points of doing this.
- The shell can read commands directly from a shell script file. As article points out, a shell can also read commands from its standard input, but that can cause some problems. Article 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 explains. Article 45.27 shows how to turn off echoing while your script reads a "secret" answer such as a password.
- Three articles- , , and - show uses for the versatile expr expression-handling command. Article . covers multiple command substitution (). The grabchars program in article is similar to read ()- but grabchars doesn't need a RETURN after the answer; grabchars also can prompt and do basic tests on the answer.
Article shows a trick for making one case statement () test two things at once. Article has a trick for simulating arrays in the Bourne Shell. Article uses echo and tr to get a control character in a script without typing the literal character into the file. Finally, article has a simple technique for getting exclusive access to a file or other system resource.
- JP