Advanced Bash-Scripting HOWTO: A guide to shell scripting, using Bash | ||
---|---|---|
Prev | Chapter 3. Tutorial / Reference | Next |
Nobody really knows what the Bourne shell's grammar is. Even examination of the source code is little help. | ||
--Tom Duff |
An interactive script is one that requires input from the user, usually with read statements (see Example 3-38).
Init and startup scripts are necessarily non-interactive, since they must run without human intervention. Many administrative and system maintenance scripts are likewise non-interactive. Unvarying repetitive tasks may usually be automated by non-interactive scripts.
Non-interactive scripts can run in the background, but interactive ones hang, waiting for input that never comes. Handle that difficulty by having an expect script or embedded here document (see Section 3.22) feed input to an interactive script running as a background job. In the simplest case, redirect a file to supply input to a read statement (read variable <file). These particular workarounds make possible general purpose scripts that run in either interactive or non-interactive modes.
If a script needs to test whether it is running in interactive mode, it is simply a matter of finding whether the prompt variable, $PS1 is set. (If the user is being prompted for input, it is, of course, necessary to display the prompt.)
if [-z $PS1] # no prompt? then # non-interactive ... else # interactive ... fi |
Most shell scripts are quick 'n dirty solutions to non-complex problems. As such, optimizing them for speed is not much of an issue. Consider the case, though, where a script carries out an important task, does it well, but runs too slowly. Rewriting it in a compiled language may not be a palatable option. The simplest fix would be to rewrite the parts of the script that slow it down. Is it possible to apply principles of code optimization even to a lowly shell script?
Check the loops in the script. Time consumed by repetitive operations adds up quickly. Use the time and times tools to profile computation-intensive commands. Consider rewriting time-critical code sections in C, or even in assembler.
Try to minimize file i/o. Bash is not particularly efficient at handling files, so consider using more appropriate tools for this within the script, such as awk or Perl.
Try to write your scripts in a structured, coherent form, so they can be reorganized and tightened up as necessary. Some of the optimization techniques applicable to high-level languages may work for scripts, but others, such as loop unrolling, are mostly irrelevant. Above all, use common sense.
To keep a record of which user scripts have run during a particular sesssion or over a number of sessions, add the following lines to each script you want to keep track of. This will keep a continuing file record of the script names and invocation times.
# Append (>>) following to end of save file. date>> $SAVE_FILE #Date and time. echo $0>> $SAVE_FILE #Script name. echo>> $SAVE_FILE #Blank line as separator. # Of course, SAVE_FILE defined and exported as environmental variable in ~/.bashrc # (something like ~/.scripts-run) |