Shell scripts are very frequently written quickly for a single purpose, used once and discarded.
They are also as frequently kept and used many times, and migrate into other uses, but often
do not receive the same level of testing and debugging that other software would be given
in the same situation. It is possible to apply general principles of good software
engineering to shell scripts.
Preface scripts with a statement of purpose, author, date and revision notes
Use a revision control system for complex scripts with a long lifetime
Assume your script will have a long lifetime unless you are certain it won't
Document any non-standard external utilities which your script needs
Document your scripts with inline comments - you'll need them in a few months when you edit it.
Treat standard input and output in the normal way, so that your script can be used
in combination with other programs (the Unix toolkit philosophy)
Be consistent in the format of your output, so that other programs can rely on it
Use options to control behaviour such as verbosity of output. Overly chatty programs are
very hard to combine with other utilities
Use interactive features (prompting the user for information) very sparingly.
Doing so renders the script unuseable in pipeline combinations with other programs, or in unattended