]> git.tuebingen.mpg.de Git - gsu.git/blob - README.md
f08718c3a1d6d57fde03babb18f3056b8a79401e
[gsu.git] / README.md
1 Introduction
2 ------------
3 gsu is a small library of bash functions intended to ease the task of
4 writing and documenting large shell scripts with multiple subcommands,
5 each providing different functionality. gsu is known to work on Linux,
6 FreeBSD, NetBSD and MacOS.
7
8 This document describes how to install and use the gsu library.
9
10 Setting up gsu
11 --------------
12 gsu is very easy to install:
13
14 ___Requirements___
15
16 gsu is implemented in bash, and thus gsu depends on bash. Bash version
17 4.3 is required. Besides bash, gsu depends only on programs which are
18 usually installed on any Unix system (awk, grep, sort, ...). Care has
19 been taken to not rely on GNU specific behavior of these programs,
20 so it should work on non GNU systems (MacOS, FreeBSD, NetBSD) as
21 well. The gui module depends on the dialog utility.
22
23 ___Download___
24
25 All gsu modules are contained in a git repository. Get a copy with
26
27                 git clone git://git.tuebingen.mpg.de/gsu.git
28
29 There is also a [gitweb](http://git.tuebingen.mpg.de/gsu.git) page.
30
31 ___Installation___
32
33 gsu consists of several independent modules which are all located
34 at the top level directory of the git repository. gsu requires no
35 installation beyond downloading. In particular it is not necessary
36 to make the downloaded files executable.  The library modules can
37 be sourced directly, simply tell your application where to find
38 it. The examples of this document assume that gsu is installed in
39 `/usr/local/lib/gsu` but this is not mandatory. `~/.gsu` is another
40 reasonable choice.
41
42 Conventions
43 -----------
44 ___Public and private functions and variables___
45
46 Although there is no way in bash to annotate symbols (functions
47 and variables) as private or public, gsu distinguishes between the
48 two. The `gsu_*` name space is reserved for public symbols while all
49 private symbols start with `_gsu`.
50
51 Private symbols are meant for internal use only. Applications should
52 never use them directly because name and semantics might change
53 between gsu versions.
54
55 The public symbols, on the other hand, define the gsu API. This API
56 must not change in incompatible ways that would break existing
57 applications.
58
59 ___`$ret` and `$result`___
60
61 All public gsu functions set the $ret variable to an integer value
62 to indicate success or failure. As a convention, `$ret < 0` means
63 failure while a non-negative value indicates success.
64
65 The `$result` variable contains either the result of a function (if any)
66 or further information in the error case. A negative value of `$ret` is
67 in fact an error code similar to the errno variable used in C programs.
68 It can be turned into a string that describes the error. The public
69 `gsu_err_msg()` function can be used to pretty-print a suitable error
70 message provided `$ret` and `$result` are set appropriately.
71
72 The subcommand module
73 ---------------------
74 This gsu module provides helper functions to ease the repetitious task
75 of writing applications which operate in several related modes, where
76 each mode of operation corresponds to a subcommand of the application.
77
78 With gsu, for each subcommand one must only write a _command handler_
79 which is simply a function that implements the subcommand. All
80 processing is done by the gsu library. Functions starting with the
81 string `com_` are automatically recognized as subcommand handlers.
82
83 The startup part of the script has to source the subcommand file of
84 gsu and must then call
85
86                 gsu "$@"
87
88 Minimal example:
89
90                 #!/bin/bash
91                 com_world()
92                 {
93                         echo 'hello world'
94                 }
95                 . /usr/local/lib/gsu/subcommand || exit 1
96                 gsu "$@"
97
98 Save this code in a file called `hello` (adjusting the installation
99 directory if necessary), make it executable (`chmod +x hello`) and try
100
101                 ./hello
102                 ./hello world
103                 ./hello invalid
104
105 Here, we have created a bash script (`hello`) that has a single "mode"
106 of operation, specified by the subcommand `world`.
107
108 gsu automatically generates several reserved subcommands, which should
109 not be specified: `help, man, prefs, complete`.
110
111 ___Command handler structure___
112
113 For the automatically generated help and man subcommands to work
114 properly, all subcommand handlers must be documented. In order to be
115 recognized as subcommand help text, comments must be prefixed with
116 two `#` characters and the subcommand documentation must be located
117 between the function "declaration", `com_world()` in the example above,
118 and the opening brace that starts the function body.
119
120 Example:
121
122                 com_world()
123                 ##
124                 ##
125                 ##
126                 {
127                         echo 'hello world'
128                 }
129
130 The subcommand documentation consists of the following parts:
131
132 - The summary. One line of text,
133 - the usage/synopsis string,
134 - free text section 1,
135 - options (if any),
136 - free text section 2.
137
138 The last three parts are optional. All parts should be separated by
139 lines consisting of two `#` characters only. Example:
140
141                 com_world()
142                 ##
143                 ## Print the string "hello world" to stdout.
144                 ##
145                 ## Usage: world [-v]
146                 ##
147                 ## Any arguments to this function are ignored.
148                 ##
149                 ## -v: Enable verbose mode
150                 ##
151                 ## Warning: This subcommand may cause the top most line of your terminal to
152                 ## disappear and may cause DATA LOSS in your scrollback buffer. Use with
153                 ## caution.
154                 {
155                         printf 'hello world'
156                         [[ "$1" == '-v' ]] && printf '!'
157                         printf '\n'
158                 }
159
160 Replace `hello` with the above and try:
161
162                 ./hello help
163                 ./hello help world
164                 ./hello help invalid
165                 ./hello man
166
167 to check the automatically generated help and man subcommands.
168
169 ___Error codes___
170
171 As mentioned above, all public functions of gsu return an error code
172 in the `$ret` variable. A negative value indicates failure, and in this
173 case `$result` contains more information about the error. The same
174 convention applies for subcommand handlers: gsu will automatically
175 print an error message to stderr if a subcommand handler returns with
176 `$ret` set to a negative value.
177
178 To allow for error codes defined by the application, the
179 `$gsu_errors` variable must be set before calling `gsu()`. Each
180 non-empty line in this variable should contain an identifier and error
181 string. Identifiers are written in upper case and start with `E_`. For
182 convenience the `$GSU_SUCCESS` variable is defined to non-negative
183 value. Subcommand handlers should set `$ret` to `$GSU_SUCCESS` on
184 successful return.
185
186 To illustrate the `$gsu_errors` variable, assume the task is to
187 print all mount points which correspond to an ext3 file system in
188 `/etc/fstab`. We'd like to catch two possible errors: (a) the file
189 does not exist or is not readable, and (b) it contains no ext3 entry.
190 A possible implementation of the ext3 subcommand could look like this
191 (documentation omitted):
192
193                 #!/bin/bash
194
195                 gsu_errors='
196                         E_NOENT         No such file or directory
197                         E_NOEXT3        No ext3 file system detected
198                 '
199
200                 com_ext3()
201                 {
202                         local f='/etc/fstab'
203                         local ext3_lines
204
205                         if [[ ! -r "$f" ]]; then
206                                 ret=-$E_NOENT
207                                 result="$f"
208                                 return
209                         fi
210                         ext3_lines=$(awk '{if ($3 == "ext3") print $2}' "$f")
211                         if [[ -z "$ext3_lines" ]]; then
212                                 ret=-$E_NOEXT3
213                                 result="$f"
214                                 return
215                         fi
216                         printf 'ext3 mount points:\n%s\n' "$ext3_lines"
217                         ret=$GSU_SUCCESS
218                 }
219
220 ___Printing diagnostic output___
221
222 gsu provides a couple of convenience functions for output. All
223 functions write to stderr.
224
225 - `gsu_msg()`. Writes the name of the application and the given text.
226
227 - `gsu_short_msg()`. Like `gsu_msg()`, but does not print the application name.
228
229 - `gsu_date_msg()`. Writes application name, date, and the given text.
230
231 - `gsu_err_msg()`. Prints an error message according to `$ret` and `$result`.
232
233 ___Subcommands with options___
234
235 Bash's getopts builtin provides a way to define and parse command line
236 options, but it is cumbersome to use because one must loop over all
237 given arguments and check the `OPTIND` and `OPTARG` variables during
238 each iteration. The `gsu_getopts()` function makes this repetitive
239 task easier.
240
241 `gsu_getopts()` takes a single argument: the optstring which contains
242 the option characters to be recognized. As usual, if a character is
243 followed by a colon, the option is expected to have an argument. On
244 return `$result` contains bash code that should be eval'ed to parse
245 the position parameters `$1`, `$2`, ... of the subcommand according
246 to the optstring.
247
248 The shell code returned by `gsu_getopts()` creates a local variable
249 `$o_x` for each defined option `x`. It contains `true/false` for
250 options without argument and either the empty string or the given
251 argument for options that take an argument.
252
253 To illustrate `gsu_getopts()`, assume the above `com_ext3()` subcommand
254 handler is to be extended to allow for arbitrary file systems, and
255 that it should print either only the mount point as before or the
256 full line of `/etc/fstab`, depending on whether the verbose switch
257 `-v` was given at the command line.
258
259 Hence our new subcommand handler must recognize two options: `-t` for
260 the file system type and `-v`. Note that `-t` takes an argument but
261 `-v` does not. Hence we shall use the optstring `t:v` as the argument
262 for `gsu_getopts()` as follows:
263
264                 com_fs()
265                 {
266                         local f='/etc/fstab'
267                         local fstype fstab_lines
268                         local -i awk_field=2
269
270                         gsu_getopts 't:v'
271                         eval "$result"
272                         ((ret < 0)) && return
273
274                         [[ -z "$o_t" ]] && o_t='ext3' # default to ext3 if -t is not given
275                         [[ "$o_v" == 'true' ]] && awk_field=0 # $0 is the whole line
276                         fstab_lines=$(awk -v fstype="$o_t" -v n="$awk_field" \
277                                 '{if ($3 == fstype) print $n}' "$f")
278                         printf '%s entries:\n%s\n' "$o_t" "$fstab_lines"
279                         ret=$GSU_SUCCESS
280                 }
281
282 Another repetitive task is to check the number of non-option arguments
283 and to report an error if this number turns out to be invalid for the
284 subcommand in question. The `gsu_check_arg_count()` function performs
285 this check and sets `$ret` and `$result` as appropriate. This function
286 takes three arguments: the actual argument count and the minimal and
287 maximal number of non-option arguments allowed. The last argument may
288 be omitted in which case any number of arguments is considered valid.
289
290 Our `com_world()` subcommand handler above ignored any given
291 arguments. Let's assume we'd like to handle this case and
292 print an error message if one or more arguments are given. With
293 `gsu_check_arg_count()` this can be achieved as follows:
294
295                 com_world()
296                 {
297                         gsu_check_arg_count $# 0 0 # no arguments allowed
298                         ((ret < 0)) && return
299                         echo 'hello world'
300                 }
301
302 ___Global documentation___
303
304 Besides the documentation for subcommands, one might also want to
305 include an overall description of the application which provides
306 general information that is not related to any particular subcommand.
307
308 If such a description is included at the top of the script, the
309 automatically generated man subcommand will print it. gsu recognizes
310 the description only if it is enclosed by two lines consisting of at
311 least 70 # characters.
312
313 Example:
314
315                 #/bin/bash
316
317                 #######################################################################
318                 # gsu-based hello - a cumbersome way to write a hello world program
319                 # -----------------------------------------------------------------
320                 # It not only requires one to download and install some totally weird
321                 # git repo, it also takes about 50 lines of specially written code
322                 # to perform what a simple echo 'hello world' would do equally well.
323                 #######################################################################
324
325 ___HTML output___
326
327 The auto-generated man subcommand produces plain text, html, or
328 roff output.
329
330                 ./hello man -m html > index.html
331
332 is all it takes to produce an html page for your
333 application. Similarly,
334
335                 ./hello man -m roff > hello.1
336
337 creates a manual page.
338
339 ___Interactive completion___
340
341 The auto-generated `complete` subcommand provides interactive bash
342 completion.  To activate completion for the hello program, it is
343 enough to put the following into your `~/.bashrc`:
344
345                 _hello()
346                 {
347                         eval $(hello complete 2>/dev/null)
348                 }
349                 complete -F _hello hello
350
351 This will give you completion for the first argument of the hello
352 program: the subcommand.
353
354 In order to get subcommand-sensitive completion you must provide a
355 _completer_ in your application for each subcommand that is to support
356 completion. Like subcommand handlers, completers are recognized by name:
357 If a function `xxx_complete()` is defined, gsu will call it on the
358 attempt to complete the `xxx` subcommand at the subcommand line. gsu
359 has a few functions to aid you in writing a completer.
360
361 Let's have a look at the completer for the above `fs` subcommand.
362
363                 complete_fs()
364                 {
365                         local f='/etc/fstab'
366                         local optstring='t:v'
367
368                         gsu_complete_options $optstring "$@"
369                         ((ret > 0)) && return
370
371                         gsu_cword_is_option_parameter $optstring "$@"
372                         [[ "$result" == 't' ]] && awk '{print $3}' "$f"
373                 }
374
375 Completers are always called with `$1` set to the index into the array
376 of words in the current command line when tab completion was attempted
377 (see `COMP_CWORD` in the bash manual). These words are passed to the
378 completer as `$2`, `$3`,...
379
380 `gsu_complete_options()` receives the option string as `$1`, the word
381 index as `$2` and the individual words as `$3`, `$4`,... Hence we
382 may simply pass the `$optstring` and `"$@"`. `gsu_complete_options()`
383 checks if the current word begins with `-`, i.e., whether an attempt
384 to complete an option was performed. If yes `gsu_complete_options()`
385 prints all possible command line options and sets `$ret` to a
386 positive value.
387
388 The last two lines of `complete_fs()` check whether the word preceding
389 the current word is an option that takes an argument. If it is,
390 that option is returned in `$result`, otherwise `$result` is the empty
391 string. Hence, if we are completing the argument to `-t`, the awk
392 command is executed to print all file system types of `/etc/fstab` as
393 the possible completions.
394
395 See the comments to `gsu_complete_options()`,
396 `gsu_cword_is_option_parameter()` and `gsu_get_unnamed_arg_num()`
397 (which was not covered here) in the `subcommand` file for a more
398 detailed description.
399
400 The gui module
401 --------------
402 This module can be employed to create interactive dialog boxes from a
403 bash script. It depends on the dialog(1) utility which is available on
404 all Unix systems. On Debian and Ubuntu Linux it can be installed with
405
406                 apt-get install dialog
407
408 The core of the gui module is the `gsu_gui()` function which receives
409 a _menu tree_ as its single argument. The menu tree defines a tree
410 of menus for the user to navigate with the cursor keys. As for a
411 file system tree, internal tree nodes represent folders. Leaf nodes,
412 on the other hand, correspond to _actions_. Pressing enter activates a
413 node. On activation, for internal nodes a new menu with the contents of
414 the subfolder is shown. For leaf nodes the associated _action handler_
415 is executed.
416
417 Hence the application has to provide a menu tree and an action handler
418 for each leaf node defined in the tree. The action handler is simply a
419 function which is named according to the node. In most cases the action
420 handler will run dialog(1) to show some dialog box on its own. Wrappers
421 for some widgets of dialog are provided by the gui module, see below.
422
423 ___Menu trees___
424
425 The concept of a menu tree is best illustrated by an example. Assume
426 we'd like to write a system utility for the not-so-commandline-affine
427 Linux sysadmin next door. For the implementation we confine ourselves
428 with giving some insight in the system by running lean system commands
429 like `df` to show the list of file system, or `dmesg` to print the
430 contents of the kernel log buffer. Bash code which defines the menu
431 tree could look like this:
432
433                 menu_tree='
434                         load_average System load
435                         processes Running processes of a user
436                         hardware/ Hardware related information
437                                 cpu Show prozessor type and features
438                                 scsi Show SCSI devices
439                         storage/ Filesystems and software raid
440                                 df List of mounted filesystems
441                                 mdstat Status of software raid arrays
442                         log/ System and kernel logs
443                                 syslog System log
444                                 dmesg Kernel log
445                 '
446
447 Each line of the menu tree consists of an identifier, suffixed with an
448 optional slash, and a description. The identifier becomes part of the
449 name of a bash function and should only contain alphabetic characters
450 and underscores. The description becomes the text shown as the menu
451 item. Identifiers suffixed with a slash are regarded as internal nodes
452 which represent submenus. In the above tree, `hardware/`, `storage/`
453 and `log/` are internal nodes. All entries of the menu tree must be
454 properly indented by tab characters.
455
456 ___Action handlers___
457
458 Action handlers are best explained via example:
459
460 Our application, let's call it `lsi` for _lean system information_,
461 must provide action handlers for all leaf nodes. Here is the action
462 handler for the `df` node:
463
464                 lsi_df()
465                 {
466                         gsu_msgbox "$(df -h)"
467                 }
468
469 The function name `lsi_df` is derived from the name of the script
470 (`lsi`) and the identifier of the leaf node (`df`). The function simply
471 passes the output of the `df(1)` command as the first argument to the
472 public gsu function `gsu_msgbox()` which runs dialog(1) to display
473 a message box that shows the given text.
474
475 `gsu_msgbox()` is suitable for small amounts of output. For essentially
476 unbounded output like log files that can be arbitrary large, it is
477 better to use `gsu_textbox()` instead which takes a path to the file
478 that contains the text to show.
479
480 To illustrate `gsu_input_box()` function, assume the action handler
481 for the `processes` leaf node should ask for a username, and display
482 all processes owned by the given user. This could be implemented
483 as follows.
484
485                 lsi_processes()
486                 {
487                         local username
488
489                         gsu_inputbox 'Enter username' "$LOGNAME"
490                         ((ret != 0)) && return
491                         username="$result"
492                         gsu_msgbox "$(pgrep -lu "$username")"
493                 }
494
495 Once all other action handlers have been defined, the only thing left
496 to do is to source the gsu gui module and to call `gsu_gui()`:
497
498                 . /usr/local/lib/gsu/gui || exit 1
499                 gsu_gui "$menu_tree"
500
501 ___Example___
502
503 The complete lsi script below can be used as a starting point for your
504 own gsu gui application. If you cut and paste it, be sure to not turn
505 tab characters into space characters. The script must be named "lsi".
506
507                 #!/bin/bash
508
509                 menu_tree='
510                         load_average System load
511                         processes Running processes of a user
512                         hardware/ Hardware related information
513                                 cpu Show prozessor type and features
514                                 scsi Show SCSI devices
515                         storage/ Filesystems and software raid
516                                 df List of mounted filesystems
517                                 mdstat Status of software raid arrays
518                         log/ System and kernel logs
519                                 syslog System log
520                                 dmesg Kernel log
521                 '
522
523                 lsi_load_average()
524                 {
525                         gsu_msgbox "$(cat /proc/loadavg)"
526                 }
527
528                 lsi_processes()
529                 {
530                         local username
531
532                         gsu_inputbox 'Enter username' "$LOGNAME"
533                         ((ret < 0)) && return
534                         username="$result"
535                         gsu_msgbox "$(pgrep -lu "$username")"
536                 }
537
538                 lsi_cpu()
539                 {
540                         gsu_msgbox "$(lscpu)"
541                 }
542
543                 lsi_scsi()
544                 {
545                         gsu_msgbox "$(lsscsi)"
546                 }
547
548                 lsi_df()
549                 {
550                         gsu_msgbox "$(df -h)"
551                 }
552
553                 lsi_mdstat()
554                 {
555                         gsu_msgbox "$(cat /proc/mdstat)"
556                 }
557
558                 lsi_dmesg()
559                 {
560                         local tmp="$(mktemp)" || exit 1
561
562                         trap "rm -f $tmp" EXIT
563                         dmesg > $tmp
564                         gsu_textbox "$tmp"
565                 }
566
567                 lsi_syslog()
568                 {
569                         gsu_textbox '/var/log/syslog'
570                 }
571
572                 . /usr/local/lib/gsu/gui || exit 1
573                 gsu_gui "$menu_tree"
574
575 The config module
576 -----------------
577 Some applications need config options which are not related to
578 any particular subcommand, like the URL of a web service, the path
579 to some data directory, or a default value which is to be used by
580 several subcommands. Such options do not change frequently and are
581 hence better stored in a configuration file rather than passed to
582 every subcommand that needs the information.
583
584 The config module of gsu makes it easy to maintain such options and
585 performs routine tasks like reading and checking the values given in
586 the config file, or printing out the current configuration. It can
587 be used stand-alone, or in combination with either the subcommand or
588 the gui module.
589
590 ___Defining config options___
591
592 To use the config module, you must define the `$gsu_options`
593 bash array.  Each config option is represented by one slot in this
594 array. Here is an example which defines two options:
595
596                 gsu_options=(
597                 "
598                 name=fs_type
599                 option_type=string
600                 default_value=ext3
601                 required=false
602                 description='file system type to consider'
603                 help_text='
604                         This option is used in various contexts. All
605                         subcommands which need a file system type
606                         use the value specified here as the default.
607                 '
608                 "
609                 "
610                 name=limit
611                 option_type=num
612                 default_value=3
613                 required=no
614                 description='print at most this many lines of output'
615                 "
616                 )
617
618 Each config option consists of the following fields:
619
620 - `name`. This must be a valid bash variable name. Hence no special
621 characters are allowed.
622
623 - `option_type`. Only `string` and `num` are supported but additional
624 types might be supported in future versions. While string variables
625 may have arbitrary content, only integers are accepted for variables
626 of type `num`.
627
628 - `default_value`. The value to use if the option was not specified.
629
630 - `required`. Whether gsu considers it an error if the option was
631 not specified. It does not make sense to set this to `true` and set
632 `default_value` at the same time.
633
634 - `description`. Short description of the variable. It is printed by
635 the `prefs` subcommand.
636
637 - `help_text`. Optional long description, also printed by `prefs`.
638
639 To enable the config module you must source the config module of gsu
640 after `$gsu_options` has been defined:
641
642                 . /usr/local/lib/gsu/config || exit 1
643
644 ___Passing config options to the application___
645
646 There are two ways to pass the value of an option to a gsu application:
647 environment variable and config file. The default config file is
648 `~/.$gsu_name.rc` where `$gsu_name` is the basename of the application,
649 but this can be changed by setting `$gsu_config_file`. Thus, the
650 following two statements are equivalent
651
652                 fs_type=xfs hello fs
653                 echo 'fs_type=xfs' > ~/.hello.rc && hello fs
654
655 If an option is set both in the environment and in the config file,
656 the environment takes precedence.
657
658 The `$gsu_config_file` variable can actually contain more than one
659 filename, separated by spaces. The config files are processed in
660 order, so that an option that is specified in the second config file
661 overwrites the definition given in the first. This is useful for
662 applications which implement a system-wide config file in addition
663 to a per-user config file.
664
665 ___Checking config options___
666
667 The gsu config module defines two public functions for this purpose:
668 `gsu_check_options()` and `gsu_check_options_or_die()`. The latter
669 function exits on errors while the former function only sets `$ret`
670 and `$result` as appropriate and lets the application deal with the
671 error. The best place to call one of these functions is after sourcing
672 the config module but before calling `gsu()` or `gsu_gui()`.
673
674 ___Using config values___
675
676 The name of an option as specified in `$gsu_options` (`fs_type` in
677 the example above) is what users of your application may specify at
678 the command line or in the config file. This leads to a mistake that
679 is easy to make and difficult to debug: The application might use a
680 variable name which is also a config option.
681
682 To reduce the chance for this to happen, `gsu_check_options()` creates
683 a different set of variables for the application where each variable
684 is prefixed with `${gsu_name}`. For example, if `$gsu_options` as above
685 is part of the hello script, `$hello_fs_type` and `$hello_limit` are
686 defined after `gsu_check_options()` returned successfully. Only the
687 prefixed variants are guaranteed to contain the proper value, so this
688 variable should be used exclusively in the application. The
689 prefix may be changed by setting `$gsu_config_var_prefix` before calling
690 `gsu_check_options()`.
691
692 ___com_prefs()___
693
694 For scripts which source both the subcommand and the config module, the
695 auto-generated `prefs` subcommand prints out the current configuration
696 and exits. The description and help text of the option as specified
697 in the `description` and `help_text` fields of `$gsu_options` are shown
698 as comments in the output. Hence this output can be used as a template
699 for the config file.
700
701 List of public variables
702 ------------------------
703 - `$gsu_dir`. Where gsu is installed. If unset, gsu guesses
704 its installation directory by examining the `$BASH_SOURCE` array.
705
706 - `$gsu_name`. The name of the application. Defaults to `$0` with
707 all leading directories removed.
708
709 - `$gsu_banner_txt`. Used by both the subcommand and the gui
710 module. It is printed by the man subcommand, and as the title for
711 dialog windows.
712
713 - `$gsu_errors`. Identifier/text pairs for custom error reporting.
714
715 - `$gsu_config_file`. The name of the config file of the application.
716 Defaults to `~/.${gsu_name}.rc`.
717
718 - `$gsu_options`. Array of config options, used by the config module.
719
720 - `$gsu_config_var_prefix`. Used by the config module to set up
721 the variables defined in `$gsu_options`.
722
723 - `$gsu_package`. Text shown at the bottom left of the man page,
724 usually the name and version number of the software package. Defaults
725 to `$gsu_name`.
726
727 License
728 -------
729 gsu is licensed under the  GNU LESSER GENERAL PUBLIC LICENSE (LGPL), version 3.
730 See COPYING and COPYING.LESSER.
731
732 Contact
733 -------
734 Send beer, pizza, patches, improvements, bug reports, flames,
735 (in this order), to Andre Noll <maan@tuebingen.mpg.de>.
736
737 References
738 ----------
739 - [bash](http://www.gnu.org/software/bash/bash.html)
740 - [dialog](http://www.invisible-island.net/dialog/dialog.html)
741 - [The author's home page](http://people.tuebingen.mpg.de/maan/)