Overview
- What Is The GNU BASH?
- GNU BASH is the GNU project's UNIX shell. It replaces the (not really)
standard UNIX Bourne and Korn shells.
- Portability
- BASH (/bin/bash) is available for all UNIX systems that I know
of. BASH scripts can be ported to other UNIX shell languages: the closest is
the Korn shell.
- Pros and Cons
- Pros: freely available and standardised. Follows the POSIX standard; has
the best of all the UNIX shells in one package. Cons: not necessarily
installed on your UNIX box.
- How To Get It
- Get it from your local GNU shoppe. BASH and the other GNU tools are part
of all Linux distributions.
Working With The GNU Borne-Again Shell
Example of code
Code fragments:
################# MODULE FUNCTION NAME #################
function module_function_name
{
return # Empty module needs 'return'
}
function private_function_name {
the_next_event=$ok_event
raise_exception $error_event
}
Programming with UNIX Shells
- You must remember to assign events and other variables as follows:
the_next_event=$some_event. If you make the common mistake of
forgetting the '$', the results are interesting but not useful. The schema
checks against this error, at a slight cost in runtime. You can skip these
checks by using the -nocheck option. The BASH language lets you declare
numeric variables explicitly, so this check is not required in the
lrschema.bsh schema.
- Your .mod file is not copied entirely, but in sections. The
script schemas extract three sections marked with the keywords <HELP>
to <END>, <DATA> to <END>, and <CODE> to
<END>. You will see :include commands in the schemas that do this.
The final <END> is optional, and probably best to ignore.
- The <HELP> section is copied to the header of the script. Each line
in this section should start with '#'. Some of my scripts are
self-anotating: if run with '-h' as argument, they do something like
this:
expand $0 | egrep "^# |^#$" | cut -c 4-80 | more
- The module Initialise_the_program gets the command-line
arguments; ie. it can refer to $1, $2, in the normal way.
- The script_name variable contains the command-line variable $0.
You could put something like this in initialise_the_program:
if test "$1" = "-h"; then
expand $script_name | egrep "^# |^#$" | cut -c 4-80 | more
exit
fi
Also note that:
- It is sometimes useful to start a script using the . operator.
For instance, to trace a script you could use these commands:
set -x; . scriptname
If such a script ends with exit (and the generated ones do), you
exit the current shell. If it's your main shell, you are logged-out. To
avoid this, enclose the entire command in parentheses:
(set -x; . scriptname)
or run a sub-shell first.
- The auto-annotating function explained above won't work if you run the
script using the . operator ($0 becomes the name of the
shell...).
- These shell script schemas are somewhat slow. I optimised the code to
use as many internal commands as possible in place of external commands.
This cut the time spent in the dialog manager code by 60% over the first
version. The bash and ksh versions are the most efficient; bsh does not have
a let command, so I need to use the clumsy a = `expr 1 + 1`
to increment a variable. The bash shell version is the cleanest, since I can
use declare to define numeric variables. Any attempt to assign text
to a numeric variable gives an explict shell error message.
- I use a function LR_idx to access arrays of numbers by shifting
and returning a numeric value. This is the fastest method I could find, and
it works in all three shell languages. As a consequence, there is a limit of
254 events (255 is the terminate_event).
- If you are doing heavy shell-type programming, consider using Perl.