clishe - A CLI Shell Library
Provides a set of function for creating command line interface scripts in Bourne Again Shell (bash) easily.
See samples directory or EXAMPLES section below for examples.
Before building and installing clishe, make sure you have installed pod2man, pod2html, podchecker and shellcheck on your system.
Next, get the tarball and unpack it or, if you want the most recent snapshot, clone the clishe repository:
$ git clone --recurse-submodules https://github.com/i386x/clishe.git
Inside the clishe top directory, type:
$ make && make install
This will install clishe and all its documentation under the /usr/local location. To change the install destination, use PREFIX:
$ PREFIX=/usr make install
This will install clishe under the /usr location.
To use clishe, simply insert the following line to your script:
. /usr/local/share/clishe/clishe.sh
You can also use a more robust way:
SCRIPTDIR="$(readlink -f "$(dirname "$0")")"
CLISHEPATH="${SCRIPTDIR}:/usr/local/share/clishe:/usr/share/clishe"
PATH="${CLISHEPATH}${PATH:+:}${PATH}" \
. clishe.sh >/dev/null 2>&1 || {
echo "clishe library is not installed"
exit 1
}
This will prefer bundled clishe.sh with your script over clishe.sh from /usr/local/share/clishe and clishe.sh from /usr/local/share/clishe over clishe.sh from /usr/share/clishe.
Do not forget also to initialize clishe before using anything from it:
clishe_init
CLISHE_COLOR - set a color of text printed by clishe_echo. See clishe_echo for more details.
CLISHE_NOCOLOR - if non-empty, suppress colored output of clishe_echo. See clishe_echo for more details.
CLISHE_QUITE - if non-empty, suppress clishe_echo's output. See clishe_echo for more details.
CLISHE_HELP_INDENT1 - spaces before option name in help screen. See clishe_defopt.
CLISHE_HELP_INDENT2 - spaces before paragraph with option description. See clishe_defopt.
clishe_scriptname - a base name of the script. See clishe_defopt for example of use.
clishe_helplines - holds the description of defined script options. See clishe_defopt.
clishe_nopts - a number of options processed by clishe_process_options. See clishe_process_options.
clishe_tailopts - a list of options that was on a tail of command line. See clishe_defopt and clishe_process_options for better explanation.
Initialize clishe shell library. This function should be invoked before any other function from clishe library is invoked.
Globally set the value of a variable.
Usage:
clishe_setvar VARIABLE VALUE
A variable name.
A value to be assigned to VARIABLE.
Assign VALUE to VARIABLE.
Print a text given in parameters to the standard output.
Usage:
clishe_echo [-X|--red|--green|--blue|--yellow|--color COLOR_CODE] \
[MSG1 [MSG2 [...]]]
Option of the form -X is passed directly to echo, i.e.
clishe_echo -n "foo"
is the same as
echo -n "foo"
Print text in red color.
Print text in green color.
Print text in blue color.
Print text in yellow color.
Print text in COLOR_CODE color. The COLOR_CODE must be written in a way so
\e[${COLOR_CODE}m
is a valid ANSI escape color code. For example
clishe_echo --color '33;1' "foo"
prints foo in yellow to the terminal window.
Messages to be printed. When printed, a space character is put between two messages.
To set a color, environment variable CLISHE_COLOR can be set to the value of the same format as in the case of COLOR_CODE. Therefore,
CLISHE_COLOR='33;1' clishe_echo "foo"
prints foo in yellow. The value of CLISHE_COLOR can be overriden by command line arguments, so
CLISHE_COLOR='33;1' clishe_echo --red "foo"
prints foo in red instead of yellow. If CLISHE_NOCOLOR has non-empty value, it suppresses color output entirely, no matter whether the color is set via CLISHE_COLOR or via command line. Thus,
CLISHE_NOCOLOR=1 CLISHE_COLOR='33;1' clishe_echo --red "foo"
prints foo in default terminal colors. If CLISHE_QUITE is set, no output is printed. For example
CLISHE_QUITE=1 CLISHE_COLOR='33;1' clishe_echo --red "foo"
prints nothing to standard output.
Print EMSG1 EMSG2 ... to the standard error output in red and exit with exit code N (if N is not specified, exit with 1).
Usage:
clishe_error [N] [EMSG1 [EMSG2 [...]]]
Exit code. Must be a positive integer. Default exit code is 1.
Error messages to be printed to the standard error output.
If the first argument matches ^[1-9][0-9]*$ (that is, if the first argument is a positive integer), it is treated as exit code instead of message text. Therefore
clishe_error "Foo:" "error"
prints Foo: error to the standard error output and exit with 1 whereas
clishe_error 2 "Foo:" "error"
prints the same but exit with 2.
As clishe_error uses clishe_echo, its output can be influenced by CLISHE_NOCOLOR and CLISHE_QUITE environment variables.
Define a command line option.
Usage:
clishe_defopt --key=STORAGE [-a [-b [...]]] -- HELP \
( required | optional [DEFAULT] )
clishe_defopt --flag [-a [-b [...]]] -- HELP ( STORAGE | help ACTION )
clishe_defopt STORAGE HELP
clishe_defopt @NAME HELP
Above, there are four forms of how to use clishe_defopt. The first form is a way of how to define key-value option. The second form is a way of how to define flag option.
The third form provide a way of how to tell clishe that there are positional options to be processed before key-value and flag options arrive. Thus
clishe_defopt USER "user name"
clishe_defopt EMAIL "user email"
clishe_defopt --help -h -- "print this screen and exit" help usage
...
tells to clishe that the first command line option is should be stored to USER, the second one to EMAIL, and the following are processed as key-value options and flags (or as tail options, see the next paragraph). Note that the order of definitions is important. If we alter first and second definition, we must also alter first and second option on command line. Also note that positional options are mandatory, so if one of them is missing it is treated as error (this does not hold for help options; in case that the help option is encountered, help action is performed even if command line options do not met the specification, except the situation when help option comes as a value of key-value option that consumes it).
The last, fourth, form tells to clishe that after the last key-value or flag option arrive zero to n positional options, called tail options. The sequence of tail options ends if command line ends or if -- was encountered. Tail options are optional, the start of tail options sequence is determined by the first option on command line that not start with dash (-). Anything between the first tail option and -- or end of command line is treated as a tail option. The processed tail options are stored to clishe_tailopts array.
This form of the first argument specify that the defined option is key-value option. key is the name of the option, STORAGE is the name of the variable to which a value of --key given on command line should be stored.
This form of the first argument specify that the defined option is flag option named flag.
A list of short options which works as an aliases/shortcuts for the long one. The list is terminated with --.
A help text to be displayed as the description of the defined option. If this option is empty (""), the help text is read from the standard input. If the option is optional key-value option, the information about its default value is appended to the help text.
The help text is accumulated in clishe_helplines variable that can be used in user defined help printing routines. Environment variables CLISHE_HELP_INDENT1 and CLISHE_HELP_INDENT2 influence the indentation of help text. Given an excerpt of help screen
Usage: script.sh [OPTIONS]
where OPTIONS are
--help, -h, -?
print this screen and exit
the spaces that are before --help, -h, -? are taken from CLISHE_HELP_INDENT1 whereas the spaces before print this screen and exit comes from CLISHE_HELP_INDENT2. If no CLISHE_HELP_INDENT1 or CLISHE_HELP_INDENT2 are provided, the default amount of spaces is 2 and 6, respectively. Because the help text is assembled dynamically during clishe_defopt invokation, it is recommended to set them before a first use clishe_defopt.
The keyword required is applicable to key-value options only. It says that the key-value option must be present on the command line and its value must be non-empty.
The keyword optional is applicable to key-value options only and it says that the key-value option is optional.
A default value of the key-value option if it was declared as optional. The default value should be specified only in connection with optional keyword. If no default value is specified, the default value of key-value option is the empty string.
A name of a variable to which the presence of flag option should be recorded. The storage variable holds the number of occurences of flag option on command line. If the corresponding flag option was not encountered during the command line processing, the storage variable remains unset. Thus, to test whether the flag option has been set, use
[[ ${STORAGE_VARIABLE:-0} -gt 0 ]]
In case of
clishe_defopt STORAGE HELP
form, STORAGE is a name of a variable to which a positional argument will be stored.
The keyword help indicates that the flag option fires a function that print a help screen.
Applicable only with help, the ACTION is the name of function that is responsible for printing of help screen.
@ serves for distinguishing between third form and fourth form of clishe_defopt. NAME is a string that is displayed on help screen, thus
clishe_defopt "@FILE1 FILE2 ..." "input files"
will result in
FILE1 FILE2 ...
input files
Following examples demonstrate how to define command line options. Consider an excerpt from a script script.sh:
clishe_defopt VMNAME "virtual machine name"
clishe_defopt --token=TOKEN -t -- "a security token" required
clishe_defopt --port=PORT -p -- "port number" optional 8888
clishe_defopt --email=EMAIL -- "email address" optional
clishe_defopt --verbose -v -- "verbosity level" V
clishe_defopt --help -h -? -- "" help usage <<__HELP__
print this screen and exit
__HELP__
clishe_defopt @FILES "input files"
function usage() {
cat <<EOF
Usage: ${clishe_scriptname} VMNAME [OPTIONS] [FILES...]
where options are
${clishe_helplines}
EOF
exit 0
}
If we run
$ ./script.sh myvm -tfa1afe1 -port=7777 -vvv
then the value of VMNAME will be myvm, the value of TOKEN will be fa1afe1, the value of PORT will be 7777, the value of EMAIL will be its default value which is the empty string, and the value of V will be 3 because there are 3 occurences of v option on command line.
If we run
$ ./script.sh myvm --token=fadeb1ade x.o y.o --help z.o
then the value of VMNAME will be myvm, the value of TOKEN will be fadeb1ade, PORT and EMAIL will keep their default values, and clishe_tailopts will contain x.o, y.o, --help and z.o. Observe that --help in this case will not print help screen.
If we run
$ ./script.sh vm1 vm2 --token=fadeb1ade --help x.o
then we get an error about missing --token option, because the vm1 is passed to VMNAME and, since vm1 not starts with dash, the rest of options are treated as tail options.
If we just run
$ ./script.sh myvm -v
we get an error about missing --token option, because this option is marked as required. If we omit myvm, we get an error about missing positional option VMNAME.
Printing the help screen is done via usage function. Notice that instead of --help, options -h and -? can be also used to show the help:
$ ./script.sh -?
Usage: script.sh VMNAME [OPTIONS] [FILES...]
where options are
VMNAME
virtual machine name
--token=TOKEN, -t
a security token
--port=PORT, -p
port number
(default: "8888")
--email=EMAIL
email address
(default: "")
--verbose, -v
verbosity level
--help, -h, -?
print this screen and exit
FILES
input files
Process command line options and store the number of processed options to clishe_nopts.
Usage:
clishe_process_options [OPT1 [OPT2 [...]]]
The general format of command line is
<positional opts> <key-value and flag opts> <tail opts> -- <the rest>
positional opts are specified with the third form of clishe_defopt, key-value and flag opts are specified with the first and second form of clishe_defopt and tail opts are specified with the fourth form of clishe_defopt and they are stored into clishe_tailopts array. -- works as the options end marker, the rest remains unprocessed.
Options to be processed. If one of the options is --, the processing is terminated.
Given an excerpt from script.sh
clishe_process_options "$@"
after running script.sh as
$ ./script.sh --foo=bar -x -- a b c
options --foo=bar and -x will be processed. When -- will be reached, it will be consumed and the processing of options will be terminated. The value of clishe_nopts variable becomes 3. The value of clishe_nopts can be used for shifting command line options to get the access to the yet unprocessed part of command line.
The following Bash script prints information about its argumetns:
#!/bin/bash
set -euo pipefail
SCRIPTDIR="$(readlink -f "$(dirname "$0")")"
CLISHEPATH="${SCRIPTDIR}:/usr/local/share/clishe:/usr/share/clishe"
PATH="${CLISHEPATH}${PATH:+:}${PATH}" \
. clishe.sh >/dev/null 2>&1 || {
echo "clishe library is not installed"
exit 1
}
clishe_init
clishe_defopt ARG1 "positional argument #1"
clishe_defopt ARG2 "positional argument #2"
clishe_defopt --token=TOKEN -t -- "security token" required
clishe_defopt --user=USER -u -- "" optional "Jane Doe <jd@compant.com>" <<EOF
a user name and email; please, keep the following format
Name Surname <your@email.address>
the email part is optional
EOF
clishe_defopt --prefix=PREFIX -- "prefix" optional
clishe_defopt --verbose -v -- "verbocity level" V
clishe_defopt --help -h -? -- "print this screen and exit" help usage
clishe_defopt "@FILE1 FILE2 ..." "input files"
function usage() {
cat <<-EOF
Show options (a clishe demo).
Usage: ${clishe_scriptname} ARG1 ARG2 [OPTIONS] [FILE1 [FILE2 [...]]]
where options are
${clishe_helplines}
The key-value options with no default value are required.
EOF
exit 0
}
clishe_process_options "$@"
shift ${clishe_nopts}
clishe_echo --blue "ARG1: '${ARG1:-}'"
clishe_echo --blue "ARG2: '${ARG2:-}'"
clishe_echo --blue "TOKEN: '${TOKEN:-}'"
clishe_echo --blue "USER: '${USER:-}'"
clishe_echo --blue "PREFIX: '${PREFIX:-}'"
clishe_echo --blue "V: ${V:-0}"
clishe_echo --blue "Files: ${clishe_tailopts[@]}"
clishe_echo --blue "Processed options: ${clishe_nopts}"
clishe_echo --blue "Rest of options: $*"
Jiří Kučera, sanczes@gmail.com
0.02
MIT
If you found a bug, please open an issue.