| Author: | absurd@olurdix.de |
|---|---|
| Date: | 20260830 |
| Copyright: | GPL-2 |
| Version: | con-dev-0.3.3.snapshot20260830093111git51b7b7c+local |
| Manual section: | 3 |
| Manual group: | bash |
#!/bin/bash -e
PATH="${PATH}:/usr/share/con-dev" . con-lib.bash
[con::include ...]
[con::cmd:depends ...]
[con::cmd:suggests ...]
con::include may be used to pull in other con-dev libraries (see below).
con::cmd:depends and con::cmd:suggests may be used to pull in non-standard program requirements (see below) that should be globally available (it is often more desirable to use this in a specific scope, though).
Note
PATH environment may be used to initialize con-dev from a non-standard installation location like so: PATH="${PATH}:/usr/local/share/con-dev" my-con-script
This is the base library for the con-dev "bash library suite"; all other libraries implicitly depend on it.
Contents
con-dev bash libraries can be globally influenced by these environment variables:
con-dev bash library code expects to be run with certain bash options enabled, so it implicitly sets these on initilization of the base library. You really should not change this precondition -- however you can if you really want to so
Source a "bash library", con-dev style.
Arguments
Globals
To add a new library implementation auto detector, just add a detect function named con_lib${LIBID}::detect:[ORDER:]${IMP}.
The detect function must return 0 only in case the resp. system is detected. It should write the resp. found "conffile" (if any) to stdout (this will be available in the code as CON_${LIBID}_CONFFILE).
Use optional [ORDER:] prefix if you want or need an order in which the detection functions are called ("sort -n" is used to order the function names; the first succeeding function wins).
Include a con-dev 'bash library'.
This is con::source with the hardcoded prefix "con".
Try some heuristics to find a version string from the version output of the command. Caution, as this will actually call the command with varying arguments.
This should probably go to a OS specific lib.
Check command lines for availability, and either run them now or set global CON_CMD_`NAME` for later use.
Arguments
You would usually use con::cmd:depends() and con::cmd:suggests() wrappers (see below) to implicitly cope with error handling.
See also: STYLEGUIDE, Compliance and Compatibility.
Examples:
# Depend on the availabilty of the tool *cryptsetup*. Sets *CON_CMD_CRYPTSETUP*. con::cmd:depends "=" "cryptsetup" # Suggests the tool *zenity*; user warning if not available. Sets *CON_CMD_ZENITY* when found. con::cmd:suggests "=" "zenity" # Depend on a tool in a non-standard location with an alternate and a custom name. Sets *CON_CMD_GIT2CL* when found. con::cmd:depends "GIT2CL" "/usr/share/gnulib/build-aux/gitlog-to-changelog" "git log --pretty --numstat --summary" # Guess distribution codename MY_PROG_CODENAME="$(con::cmd "@unknown" "lsb_release --codename --short" "uname --kernel-name")"
Like con::cmd(), but
Set terminal attributes.
Printf with terminal attributes.
Print current log level number.
Print current log level string.
true if loglevel is >= DEBUG.
Create a debug log output, for error perusal.
Initialize logging; if <LEVEL> if given, it will be checked and "normalized" to a known sane log level. <LEVEL> may be given as number or as string.
Print current log level status to stdout.
Generic log function; usually you just use one of the shortcuts below.
Log a fatal log: Issue the message, log a debug backtrace, and exit the program with error code CON_ERRSTATUS_FATAL.
Log shortcuts for all non-fatal levels. Use level notice for messages the user should usually always see.
Wrapper for bash builtin "trap", allowing multiple trap commands and subshell-local trap commands.
This is like builtin "trap", but the given command is added to the list of commands to run, and it works seemlessly for subshells. The commands are run in reverse order (i.e., last added runs first). The command line may be given just like any other shell code after the SIGSPEC.
Unlike with the builtin "trap", only one signal may be given on the command line, so that no trap functions will be overwritten; for the same reason, you must not mix this call with calls to the trap bultin directly.
Examples:
con::trap EXIT rm -v "my temp file with spaces" con::trap ERR printf "%s\n" "Ough, some error occured." con::trap SIGALRM printf "%s\n" "Got alarm signal."
Set up internal variables for later catch handling, and fail with errStatus.
This will stop processing at this point, and the run all traps set up for ERR -- until the final (internal) catch trap which will do the generic error handling, and exits the script.
Catch and finalize an error trap.
Wrapper for mktemp(1) with automatic removal on script exit.
Various tools and helpers around bash variables.
Note
bash 4.2 and 4.3 have introduced further features to help with variable handling. Even with 4.3 however, there is still not enough support to get rid of this evilry completely, plus we currently support compatibility down to 4.2. So for the time being, most of these helpers are still used or needed.
| Version | con-dev | Feature | Notes |
| 2.0 | ✔ | ${!var} | Should be preferred over con::var:get where convenient. |
| 4.2 | ✔ | declare -g / local -g | Obsoletes con::var:set, con::var:setArray when global variables should be set (still needed to set variables in-scope only). |
| 4.3 | ✗ | declare -n / local -n | May be used as alternative to con::var:get or code like ivar="${a}_${b}"; printf "${!ivar}". |
Get a variable value.
For convenience, you may use this filthy little devil where the usual bash idioms ${!var} or declare -n var run short, for example:
value="$(con::var:get "VAR")" # Equivalent to ``value="${VAR}"`` (rather use the bash idiom).
value="$(con::var:get "${ivar}")" # Equivalent to ``${!ivar}`` (rather use the bash idiom).
value="$(con::var:get "${x}_${y}")" # When your variable name is a build from other variables.
value="$(con::var:get "${my}_${array}[${i}]")" # Works for arrays too...
Indirectly set a variable.
For convenience, you may use this filthy little devil where the bash syntax runs short, for example:
con::var:set "VAR" VAL # Equivalent to ``VAR="VAL"`` (rather use the bash syntax).
con::var:set "${ivar}" VALUE... # When your variable name is in a variable.
con::var:set "${x}_${y}" VALUE... # When your variable name is a build from other variables.
con::var:set "${my}_${array}[${i}]" VALUE # Works for arrays too...
Like con::var:set, but sets/adds all <value> arguments as array.
Copy array variable into another.
Copy assosiative array variable into another.
Print assosiative array variable (mostly for debugging).
Check if a variable named <varName> is set or empty, resp.
Set <varName> if unset or empty, resp.
Print code (suitable vor eval) to set a variable.
Note
This will quote using ", and escape any occurence of " in value.
Just like con::var:setVarCode, but using prefix "local ".
A list in this context is any string containing tokens separated by a special delimiter character (DSV).
By design, all these function are independent of the current IFS value; the delimiter is fixed to be the SPACE character, or must be given explicitely with any call.
1st, DSV support gives you join() and split() to convert to and from DSVs and work with bash arrays internally.
2nd, there are convenience functions to do some manipulations on DSVs directly.
Example 1: Using bash arrays internally:
declare -a MY_PROG_MY_ARRAY con::list:split MY_PROG_MY_ARRAY "my,comma,separated,list" "," ... work with MY_PROG_MY_ARRAY internally... printf "Result: %s" "$(con::list:join MY_PROG_MY_ARRAY ",")"
Example 2: Directly manipulate a DSV string:
# Add a user path to PATH to front, and delete any duplicates in PATH
PATH="$(con::list:uniq "$(con::list:prepend "${PATH}" "${HOME}/bin" ":")" ":")"
Split a list into an array variable.
Join an array variable into a list.
Test if token is in list.
Insert a token at the beginnng or end of a a list. Rather use con::list:append() or con::list:prepend() shortcuts than this function.
Append or prepend a token to a list.
Remove duplicates from list.
Reverse list tokens ("A B C" -> "C B A").
Check if function exists.
Print defined function names, optionally limited by REGEX.
Monkey-copy a function.
Monkey-rename a function.
Option support for functions.
This allows to have proper option arguments for functions like those known from executables. It requires the eval trick, and will also considerably slow things down, so usage should be limited to "top level" functionality.
Example:
my_function()
{
eval "$(con::func:getopts "p=Value" "d=" "T=string" 0 : "${@}")"
if ${_d_given}; then
printf "-d given: %s\n" "${_d}"
fi
...
}
...
my_function -p 3 -d 17 -T int
Helper: Set readline history and bind TAB to history completion.
Validate, readline-complete or bash-complete a variable type.
con-dev variant of bash builtin read.
con::ui:read wrapper for simple yes/no questions.
Compare versions (via coreutil's 'sort --version-sort').
Convert a arbitrary string to an identifier usually suitable for technical purposes.
Extract a submatch from regular expression.
Get arithmetic maximum for any relation.
Get arithmetic maximum or minimum, resp.
Run <command> for each argument given as first argument.
Run command, be quiet on success.
Run <command> for each character in <string> as first argument.
Run <COMMAND> for each line in stdin as first argument.
Filter each line to be prefixed by <prefix>.
Backtrace using builtin "caller" for all found levels.