Bashkit

Erik Adelbert

Hugues Morisset

What is bashkit

Bashkit is an opiniated scripting model and framework for Bash 5.x. It is intended to help writing more robust scripts in which unhandled errors are preferably fatal. It does so by enforcing and exploiting selected bashisms and sometimes moving away from IEEE POSIX P1003.2/ISO 9945.2. It supplements bash as a collection of modules akin to a script development library. It consists mostly in pure bash functions with very few dependencies.

Bashkit is a scripting model that proposes idioms and tools for:

Bashkit comes with 7 core and 11 standard function modules. A bashkit script is a bash script that, at some point sources bashkit and modules and starts calling their functions. Custom modules are easy to write and module boilerplates are kept small. Nonetheless, a proper error handling surely requires editing.

Core modules implement:

Standard modules bring:

A module can be loaded either when sourcing Bashkit or by calling bashkit::load(1)

  source bashkit.bash check shopt # load bashkit along with check and shopt modules
  bashkit::load array # load array module

Download

Stable releases can be found at wuage.

Documentation

Documentation for Bashkit is available online. You may also find information on Bashkit by running TODO.

Mailing Lists

TODO

Getting involved

TODO

Development

TODO

Translating Bashkit

TODO

Maintainer

TODO

Definitions

These definitions are used throughout the remainder of this manual.

POSIX
A family of open system standards based on Unix. Bash and Bashkit are primarily concerned with the Shell
and Utilities portion of the POSIX 1003.1 standard.

blank
A space or a tab character.

builtin
A command that is implemented internally by the shell itself, rather than by an executable program
somewhere in the file system.

control operator
A token that performs a control function. It is a newline or one of the following:
‘||’, ‘&&’, ‘&’, ‘;’, ‘;;’, ‘;&’, ‘;;&’, ‘|’, ‘|&’, ‘(’, or ‘)’.

exit status or error code or errcode
The value returned by a command to its caller. The value is restricted to eight bits,
so the maximum value is 255.

field
A unit of text that is the result of one of the shell expansions. After expansion, when
executing a command, the resulting fields are used as the command name and arguments.

filename
A string of characters used to identify a file.

job
A set of processes comprising a pipeline, and any processes descended from it, that are
all in the same process group.

job control
A mechanism by which users can selectively stop (suspend) and restart (resume) execution
of processes.

metacharacter
A character that, when unquoted, separates words. A metacharacter is a space, tab, newline,
or one of the following characters: ‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’.

name
A word consisting solely of letters, numbers, and underscores, and beginning with a letter
or underscore. Names are used as shell variable and function names. Also referred to as an
identifier.

operator
A control operator or a redirection operator. See Redirections, for a list of redirection
operators. Operators contain at least one unquoted metacharacter.

process group
A collection of related processes each having the same process group ID.

process group ID
A unique identifier that represents a process group during its lifetime.

reserved word
A word that has a special meaning to the shell. Most reserved words introduce shell flow
control constructs, such as for and while.

return status
A synonym for exit status.

signal
A mechanism by which a process may be notified by the kernel of an event occurring in
the system.

special builtin
A shell builtin command that has been classified as special by the POSIX standard.

token
A sequence of characters considered a single unit by the shell. It is either a word or
an operator.

word
A sequence of characters treated as a unit by the shell. Words may not include unquoted
metacharacters.

Table of Contents

  1. Logging
    1. Standard logging
    2. JSON logging
    3. Panicking
    4. Report and Trace
  2. Error Handling
    1. Discussion
    2. Error code mapping
    3. Flow of control with true
    4. raise, catch and resume
  3. Bashkit scripting
    1. Unhandled errors
    2. Fail fast
    3. Traps and cleanup
    4. Colors

Basic Bashkit features

Bashkit is an acronym for Bourne-Again SHell KIT. It supplements Bash and can not be used without. This chapter briefly summarizes the bashkit’s building blocks: logging, control structures, functions, and how the shell executes commands with active bashkit.

Logging

Bashkit as a proper software framework offers a logging system. A bashkit script can and should record software events in a structured way. Bashkit follows syslog(1) levels to implement logging routines:

routine panic alert crit error warn note info debug
level 0 1 2 3 4 5 6 7

Logging level is controlled either by setting the global variable $LOGLEVEL beforehand or by calling logging:setlevel at runtime. Default logging level is INFO/6. As expected, a logging routine displays a message when the current logging level is lower or equal to its own, otherwise the message is silenced but planned side-effects occur (see errcode).

there’s a bashkit routine named info. It shadows info(1) the bash info document reader. If you need to use info(1), call it with command info [args].

Example:

bash-5.2$ cat hello.bash
#!/usr/bin/env bash
source ${SOME_PATH_TO_BASHKIT}/bashkit.bash
info 'hello world!'

bash-5.2$ bash -c ./hello.bash
2022-10-12 18:27:33+0200 [ info] ./hello.bash:3| hello world!

Standard logging

Standard logging happens on stderr, when on a supported terminal it is colorized by default. Whenever color is unsuitable, it can be disabled by setting the global variable $NO_COLOR. As shown in hello.bash example, standard logging routines display a default format:

YYYY-MM-DD HH:MM:SS+hhmm [LEVEL] ORIGIN:LINENO| MSG
field format
STAMP ISO-8601 extended offset date-time format
LEVEL routine name in a padded string of length 5, enclosed in brackets
ORIGIN $FUNCNAME or $FILENAME or main or bash
LINENO integer of calling time $LINENO value
MSG arbitrary bash expandable string after “|”

JSON logging

JSON logging happens on stderr, it is enabled by setting the global variable $JSON beforehand. When activated, it replaces standard logging output. Messages are emitted in NDJSON format and consist in valid json values with no color and a fix layout:

'{ "date": "STAMP", "level": "LEVEL", "func": "ORIGIN", "lineno": "LINENO", "text": "MSG" }\n'

Fields STAMP, LEVEL, …, MSG are similar to standard logging except for LEVEL that is not padded nor bracketed. They are all enclosed in double-quotes.

Example:

bash-5.2$ bash -c 'JSON=1 ./hello.bash'
{ "date": "2022-10-13 17:35:04+0200", "level": "info", "func": "./hello.bash", "lineno": "3", "text": "hello world!" }
bash-5.2$

Panicking

panic and fatal are special logging routines that stop the ordinary flow of control and begin panicking:

Panics can only be initiated by invoking panic or fatal directly.

Report and Trace

Report mode is controlled by setting the global variable $REPORT. When activated, the script will dump a stack-trace and exit whenever an error is detected by bashkit.

Trace mode is controlled by $TRACE. When activated:

Error handling

Bashkit proposes a unique yet classical error handling coding patterns. They extend bash error semantic by exploiting conditional statements. They assemble into error handling pipelines. Bashkit uses a trap to catch errors as they arise. If they are handled locally, the flow of control proceeds. Otherwise, the error is bubbled up the calling stack until handled. When an unhandled error reaches its calling-stack root, the calling script usually crashes. In Bashkit, almost all errors are fatal.

Discussion

Handling error in bash is difficult: The query “error handling in bash”, on the biggest search engine, returns +88M links as of October 2022. On SO, a closely related question, asked in 2008, was viewed +410k times and received answers as late as early 2022. Eventually, it was deemed “opinion-based” by moderators and closed to more answers.

Bash basic exit status handling is flawed by decisions made early during bash design along with heavy POSIX constraints on the subject. The resulting set -e mode is unsatisfactory and error-prone: whenever scripts are thought to fail fast, they could just behave in unintuitive ways, fallen into one of the many bash pitfalls.

Bashkit helps scripts to efficiently handle errors or fail fast in most of the cases. One should be aware that some bash quirks are simply unreachable to address within bash itself. Don’t do this:

diff <(sort A) <(sort B)

Error code mapping

Bashkit defines an error code mapping that closely follows bash definition and adds additional constraints to it:

range names owner note
0-3 E_SUCCESS - E_UNSUPPORTED bash
4-7 N/A unused
8-32 E_BASHKIT - E_CUSTOM bashkit highest bit is 3 or 4
33-123 custom names user highest bit is 5 or 6 but err < 124
124-128 E_TIMEOUT - E_INVALID_EXIT bash
129-192 E_SIGHUP - E_SIGRTMAX signal highest bit is 7 low bits for signum
193-254 N/A unused
255 E_OUT_OF_RANGE bash

bashkit offers tools to manipulate errors (see error)

Flow of control with true

Using true as a control flow mechanism is already a bash idiom:

#!/usr/bin/env bash
up_the_game
rm some_random_file_that_could_not_exist || true
echo "all went well!"

Under errcode, the bashkit error handling system, you can do the same:

source bashkit.bash

up_the_game
rm some_random_file_that_could_not_exist || true
echo "all went well!"

true, is the most basic errcode handler of all. Using true to handle an error means this error is irrelevant to the flow of control.

return and exit are also errcode compatible so existing constructs are preserved.

raise, catch and resume

check_cmd() {
    command -v "${cmd}" &> /dev/null
}

command is a bash builtin. When used with -v option, it prints a description similar to the type builtin. It returns exit status 0 if $cmd is executable or fails with 1 if not. As stated before, under errcode (bashkit error handling support) when $cmd is not available, it is a fatal error. To be more on point, check_cmd should be more flexible than silently failing (thanks to redirecting to /dev/null), it could at least log an error. Consider the bashkit idiom to just do that:

check_cmd() {
    local cmd=$1
    command -v "${cmd}" &> /dev/null \
    || error "${cmd} not found"
}

bash-5.2$ bash -c 'source bashkit.bash; check_cmd(){... ; check_cmd inexistent'
2022-10-17 16:18:02+0200 [error] bash:1| inexistent not found

It is slightly better but still lacks some genericity: what if we just want to know if a command exists and proceed with a workaround if not? Enter raise that ultimately enables more efficient error handling patterns:

source bashkit.bash

check_cmd() {
    local cmd=$1
    command -v "${cmd}" &> /dev/null \
    || raise "${cmd} not found"
}

check_cmd inexistent \
|| error

Invoked like this, raise position a message along with the exit status before returning to the caller. It becomes the caller’s responsibility to chose what to do when check_cmd fails. For now, as previously, the script logs the error and then crashes. But a more convenient flow is within reach by using catch:

source bashkit.bash

check_cmd isint \
|| {
  catch
  isint() {
     printf '%d' "$1" > /dev/null 2>&1 \
     || raise "invalid number: $1"
  }
}

isint 1 \
&& info integer \
|| error

In this situation, when check_cmd raises a failure, the catch block is able to: 1) consume this failure 2) define a replacement function

isint also complies to errcode: the last invocation logs an informational “integer” (rather than error log “invalid number”).

Now consider this example where maybe has 50% chances of failure:

source bashkit.bash

maybe()(( $1 < RANDOM%100 ))

maybe 50 \
&& echo yep \
|| echo nope # not an errcode handler

Bashkit error handling trap will stop short right after the maybe call if it fails. In the long run, the script prints “yep” in one out of two runs but will never print “nope”. Under errcode it does not work because echo is not an errcode compatible handler. The idiomatic way here, is to use resume:

source bashkit.bash

maybe()(( $1 < RANDOM%100 ))

maybe 50 \
&& echo yep \
|| resume echo nope

This time, the script will print either “yep” or “nope” with the same frequency. resume consumes the error and restores control to the command that immediately follows, in this case: echo nope.

not as a function

Because bash unary negation operator ! is not a command, resume can not transfer control to it. It can be replaced by not. not is defined to return the logical negation of its argument.

source bashkit.bash

maybe()(( $1 < RANDOM%100 ))
abort()(( RANDOM & 0x1 ))

maybe 50 \
|| resume not abort \
|| error 'can not proceed'

In the long run, this script will rather succeed (75%) than log an error and fail (25%).

Bashkit scripting

Bashkit favors fail fast like scripting patterns: by combining Conditional Constructs [[...]] and ((...)) with errcode and handlers scripts can achieve useful and robust behaviors. Bashkit scripts can setup LIFO traps on any signal and cleanup command easily enables deferred actions upon script exit. It is also very easy to add text color to outputs.

Unhandled errors

Bashkit can detect a set but unhandled error that otherwise would go silent. In this case, the script will crit log the error:

source bashkit.bash extras

isint not_an_integer

When ran, the above script outputs:

bash-5.2$ ./noint.bash
2022-10-24 15:14:52+0200 [ crit] isint:33| invalid number

Fail fast

Fail fast is a simple technique that is known to ease finding most defects in a software. A software that fails fast, will stop visibly as soon as a problem occurs: bugs are easier to find and fix so, hopefully, fewer make it to production.

Assertions

Usually assertions are different from exceptions in the way that assertions can be turned off because they were believed useful during design and tuning development stages. Experience has proven them usefull even in production where real problems happen.

Bash has no support built-in support for assertions. Bashkit which is mostly written in pure-bash does not either implement a per-se assertion system: instead it emulates them using conditional construcs and errcode: Namely a tests followed by a || raise pattern that exploits raise polymorphism is an assertion.

Example:

array::pick() {
    local -n A=$1
    local -n acc=${2:-__}

    local i=$(( RANDOM % ${#A[@]} ))
    printf -v acc '%s\n' "${A[i]}"
}

array::pick takes two bash namerefs. The first one points to an array A while the second, acc, is used to write out a random element of A. Here are the things that could go wrong within this function: 1) a wrong argument count (invocation mistake) 2) A not pointing to an array 3) A pointing to an empty array

Being a publicly exposed function of bashkit module array, array::pick should remediate these situations. The proper way is to add a bunch of tests akin to assertions and combine errcode handlers to always achieve a useful behavior:

source bashkit.bash

array::pick() {
    (( $# == 1 || $# == 2 )) \
    || raise "${E_PARAM_ERR}" 'incorrect invocation' \
    || fatal

    local -n A=$1
    local -n acc=${2:-__}

    check::vartype as A \
    || raise

    (( ${#A[@]} != 0 )) \
    || raise "${E_PARAM_ERR}" 'array is empty'

    local i=$(( RANDOM % ${#A[@]} ))
    printf -v acc '%s\n' "${A[i]}"
}

This example also shows that raise is polymorphic.

Traps and cleanup

In Bash, a process may choose to perform a different action, rather than exiting, upon receiving a signal. This is done by setting up a signal handler (or trap). The trap must be set before the signal is received. A process that receives a signal for which it has set a trap is said to have caught the signal.

The simplest signal handling a process can choose to perform is to ignore a signal. This is generally a bad idea, unless it is done for a very specific purpose. Ignoring signals often leads to runaway processes which consume all available CPU.

Bashkit trap module utilities extend bash command behavior. Namely, trap::callback enables a script to register multiple callback functions or plain sources that are called in LIFO order upon receiving selected signals.

More commonly, traps can be set up to intercept a fatal signal, perform cleanup, and then exit gracefully. For example, a program that creates temporary files might wish to remove them before exiting. If the program is forced to exit by a signal, it won’t be able to remove the files unless it catches the signal.

Bashkit cleanup utility is a trap::callback wrapper dedicated to hook instructions to signal EXIT/0. It can be called anytime from anywhere in the script, registered functions will run in LIFO order at the script top level. As in bash, a mistake in a callback could abort the entire cleanup process but won’t prevent the script from exiting.

Example:

source bashkit.bash

scratch=$(mktemp) \
|| exit

cleanup 'rm -f "${scratch}"'

When panicking, a bashkit script will cleanup before exiting. But there are situations beyond reach, like arithmetic exceptions or uncatchable signals that can prevent cleanup to take place.

Colors

Bashkit provides a color module. For now, this module only supports the ANSI 8 colors model.

color::encode supports a tiny english color description language:

description = color "text" [ color "background" ]
            | "reset"
color = ""
      | attributes brightness base
attributes=? a list of unique modifiers ?
modifiers = ""
          | "regular" | "bold" | "dim" | "italic" | "underlined" 
          | "blinking"
          | modifiers, { modifiers }
brightness = ""
           | "bright"
base = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan"
     | "white" | "default"

The smallest descriptions of all are "text" and "reset". The later is always the ANSI ESC[m reset code while the former is the current system-defined default.

Example:

source bashkit.bash

color::encode bold green text; bold_green=${__}
color::encode reset; reset=${__}

printf "%b%s%b" "${bold_green}" NATURE "${reset} does not hurry, yet everything is accomplished\n"

Declaring colors can be a tidy task, the following example shows how to build a color palette:

source bashkit.bash

declare -A COLPAL=(  # color palette
  [panic]='underlined blinking bold white text red background'
  [alert]='bold white text red background'
  [crit]='underlined bold red text'
  [fatal]='bold red text'
  [error]='red text'
  [warn]='yellow text'
  [note]='blue text'
  [info]='green text'
  [debug]='magenta text'
  [reset]='reset'
)

color::table COLPAL

The demonstrated palette is actually used by bashkit logging routines.

When called on a bash dictionary (ie. associative array), color::table will substitute, in place, each description by a computed ANSI escape sequence. The resulting dictionary is to be used later as a lookup table.

bashkit::load

bashkit::load - load a bashkit module

SYNOPSIS

note [modname …]

DESCRIPTION

With modname a string, bashkit:load takes an arbitrary number of modname arguments. modname refers to a module named <modname>.bash lying in the hierarchy pointed by the environement variable $BASHKIT_MODPATH.

bashkit::load returns success unless the module does not exist.

EXAMPLES

$ bashkit load array

ENVIRONMENT

catch

catch - store a raising errcode and resume execution

SYNOPSIS

catch [refname]

DESCRIPTION

Catch captures and stores a raising errcode and then resume execution at the first following command.

If no refname is specified, errcode is stored in special bashkit variable $____.

When catch returns, the error context is modified: $? is equal to 0.

Catch always returns with an exit code of zero.

EXAMPLES

Example 1 true(1) equivalence

The following command will never fail, it is equivalent to using true(1).

$ rm "${TMPFILE}" || catch

Example 2 Error handling

The following command, in case of failure, will print an explanation for curl(1) exit statuses [1-3] or display it otherwise.

$ curl "${URL}" > /dev/null 2>&1 || {
    catch rc;
    case ${rc} in
      1) echo "unsupported Protocol";;
      2) echo "failed to initialize";;
      3) echo "malformed URL";;
      *) echo "curl exited with status ${rc}";;
    esac
  }

SEE ALSO

raise(1), resume(1)

not

not - unary logical not as a function

SYNOPSIS

not [command]

DESCRIPTION

not is the functional equivalent of !. It is intended to be used with resume(1) that can only accept a command as argument.

EXAMPLES

Example 1 Direct invocation

The first following command always fails while the second always succeeds.

$ not true
$ not false

Example 2 Combining with resume(1)

The following command is equivalent to logical (green | ! red):

$ is_green "${color}" || resume not is_red "${color}"

SEE ALSO

resume(1)

raise

raise - raise or reraise an errcode

SYNOPSIS

raise [errcode] [errmsg]

DESCRIPTION

Raise set an errcode and an errmsg and then fails immediately.

Raise returns the given errcode. If the specified errcode is zero, the exit status defaults to one. When no errcode is specified, raise returns either the last positionned errcode or defaults to one if none.

If errmsg is not given, raise uses the last positionned one or defaults to none.

EXAMPLES

Example 1 Direct invocation

The following command always fails, here raise is equivalent to false(1).

$ raise

Example 2 Direct invocation with arguments

The first two commands fail with exit status 2, the last one with 1. In the last two, an error message is also positionned.

$ raise 2
$ raise 2 "error message"
$ raise "error message"

Example 3 Raising last exit status

The following commands will raise the exit status returned by rm(1) along with an error message for the second one.

$ rm "${TMPFILE}" \
  || raise
$ rm "${TMPFILE}" \
  || raise "cannot rm ${TMPFILE}"

Example 4 Raising exit status through calling stack

The following script will log an error and then exit with status 1. The exit status is set in isint and reused upon return by error(1).

#!/usr/bin/env bash
# isint.bash -- bashkit example
source bashkit.bash

isint() {
  local n
  printf -v n '%d' "${1:-}" &> /dev/null \
  || raise "not an int"
}

isint "abc" \
|| error

$ bash isint.bash
2022-10-31 20:44:01+0100 [error] isint:8| not an int

Example 5 Relocating errors throughout calling points

In the above example, the error message traced back into isint. It is sometimes usefull to relocate the error at the calling point:

#!/usr/bin/env bash
# isint.bash -- bashkit example
source bashkit.bash

isint() {
  local n
  printf -v n '%d' "${1:-}" &> /dev/null \
  || raise "not an int"
}

isint "abc" \
|| raise \
|| error

$ bash isint.bash
2022-10-31 20:47:38+0100 [error] isint.bash:13| not an int

SEE ALSO

catch(1), resume(1)

resume

resume - abort a raising errcode and resume execution

SYNOPSIS

resume [command]

DESCRIPTION

Unlike catch(1), resume executes in the same context as the error. It allows the flow of control to abort the raising errcode and to recover execution by running the command that follows it.

EXAMPLES

Example 1 Direct invocation

The following command always succeed, here resume is equivalent to builtin :.

$ resume

Example 2 Direct invocation with a command argument

The following command displays a message, here resume is a no-op:

$ resume echo "resumed!"

Example 3 Error flow of control handling

$ (( n > 0 && n & 0x1 )) && echo "odd" || resume echo "even"

Without resume the above command will stop short before || for any even number: it will not display “even”.

Example 4 Combining with not(1) or builtin let

resume argument must be a command, unary operator or litteral values are not supported. This is why we have to use not(1) in the following construct:

$ is_green "${color}" || resume not is_red "${color}"

The same goes for assignations:

$ is_even "${x}" || resume let x=$((x + 1))

SEE ALSO

catch(1), raise(1), not(1)

color::encode

color::encode - compute an 8 colors ANSI code from a color description

SYNOPSIS

color::encode [description]

DESCRIPTION

color::encode encodes a color description into an ANSI color escape code. The code is always stored in special bashkit variable $__.

If no description is specified, the code defaults to ESC[m, the reset code.

The description must be written according to the following grammar:

description = color "text" [ color "background" ]
            | "reset"

color = ""
      | attributes brightness base

attributes=? a list of unique modifiers ?

modifiers = ""
          | "regular" | "bold" | "dim" | "italic" | "underlined" | "blinking"
          | modifiers, { modifiers }

brightness = ""
           | "bright"

base = "black" | "red" | "green" | "yellow"
     | "blue" | "magenta" | "cyan" | "white"
     | "default"

The smallest descriptions of all are "text" and "reset". The later is always the ANSI ESC[m reset code while the former is the current system-defined default.

color::encode returns with an exit code of zero upon successful encoding. It returns E_PARAM_ERR/9 otherwise.

EXAMPLES

The description must always be written without quote when invoking directly:

  $ color::encode underlined blinking bold white text red background
  $ echo "${__}"
  \x1b[4;5;1;37;41m

SEE ALSO

https://en.wikipedia.org/wiki/ANSI_escape_code

color::table(1)

color::is_enabled

color::is_enabled - test if color is supported

SYNOPSIS

color::is_enabled

DESCRIPTION

color::is_enabled test if color is not disabled and terminal is compatible. One can disable color by setting $NO_COLOR before running scripts.

color::is_enabled returns 0 if colors are available and >0 otherwise.

EXAMPLE

$ color::is_enabled && echo "colors are available" || resume echo "no color"

SEE ALSO

color::encode(1), color::table(1)

color::table

color::table - compute 8 colors ANSI code from a description dictionary

SYNOPSIS

color::table [dict]

DESCRIPTION

color::table replaces descriptions found in an associative array by corresponding ASCII 8-color codes. The dict can subsequently be used as a lookup table.

The descriptions must be written for color::encode(1).

If there is a type mismatch or if dict is undefined, color::table panics by calling fatal(1).

color::table returns with an exit code of zero upon successful encoding. It errors with exit status E_PARAM_ERR/9 otherwise. The content of the original dict is undefined in the later case.

EXAMPLE

$ declare -A COLPAL=(  # color palette
    [panic]='underlined blinking bold white text red background'
    [alert]='bold white text red background'
    [crit]='underlined bold red text'
    [fatal]='bold red text'
    [error]='red text'
    [warn]='yellow text'
    [note]='blue text'
    [info]='green text'
    [debug]='magenta text'
    [reset]='reset'
  )
$ color::table COLPAL
$ echo "${COLPAL[panic]}"
\x1b[4;5;1;37;41m

SEE ALSO

color::encode(1), error(1), fatal(1)

breakpoint

breakpoint - set an intentional pausing place for debugging purpose

SYNOPSIS

breakpoint

DESCRIPTION

When used in conjunction of errcode::trap breakpoint mode or if $DEBUG is set beforehand, breakpoint pauses the script and throws a minimal console to /dev/tty. Otherwise, breakpoint is a no-op.

EXAMPLE

$ errcode::trap breakpoint
$ breakpoint
# breakpoint (0)
debug>

SEE ALSO

errcode::trap(1)

errcode::trap

errcode::trap - get or set errcode mode

SYNOPSIS

errcode::trap [command]

DESCRIPTION

command is one of default | enable | disable | breakpoint | status. If no command is given, it defaults to status. errcode::trap panics by calling fatal(1) otherwise.

errcode::trap returns with an exit code of zero if a errcode is enabled, >0 otherwise.

Disabling errcode trap is strongly discouraged as it may result in non obvious bad script side effects.

EXAMPLE

$ errcode::trap \
&& echo "errcode trap is enabled" \
|| resume echo "errcode is disabled"
errcode is enabled

SEE ALSO

breakpoint(1)

error::class

error::class - error classifying tool

SYNOPSIS

error::class error

DESCRIPTION

With error either a positive integer in range [0-255] or a valid name:

^E_([A-Z1-9]+)((_([A-Z1-9])+)*)$
range names owner note
0-3 E_SUCCESS - E_UNSUPPORTED bash
4-7 N/A unused
8-32 E_BASHKIT - E_CUSTOM bashkit highest bit is 3 or 4
33-123 custom names user highest bit is 5 or 6 but lesser than 124
124-128 E_TIMEOUT - E_INVALID_EXIT bash
129-192 E_SIGHUP - E_SIGRTMAX signal highest bit is 7 low bits for signum
193-254 N/A unused
255 E_OUT_OF_RANGE bash

The queried error class is printed on stdout and stored in special variable $__.

error::class returns 0 on success >0 otherwise.

EXAMPLES

$ error::class 129
signal
$ error::class E_SIGHUP
signal

SEE ALSO

error::custom(1), error::list(1), error::whatis(1)

error::custom

error::custom - register a custom error

SYNOPSIS

error::custom rawname rawcode

DESCRIPTION

With rawname a string and rawcode a positive integer in range [1-90], error::custom registers $E_<RAWerror::custom> wich equals $E_CUSTOM + rawcode.

rawname is valid if it matches:

^E_([A-Z1-9]+)((_([A-Z1-9])+)*)$

error::custom returns 0 if successful. It returns $E_PARAM_ERR when rawname or rawcode are already defined or if rawcode is out of range.

EXAMPLE

$ error::custom empty_buffer 1
$ echo "${__}"
E_EMPTY_BUFFER=33
$ echo ${E_EMPTY_BUFFER}
33

SEE ALSO

error::class(1), error::list(1), error::whatis(1)

error::list

error::list - error class listing tool

SYNOPSIS

error::list errclass

DESCRIPTION

With errclass is one of all | bash | bashkit | custom | signal. When errclass is not given it defaults to all. error::list panics by calling fatal(1) otherwise.

range names owner note
0-3 E_SUCCESS - E_UNSUPPORTED bash
4-7 N/A unused
8-32 E_BASHKIT - E_CUSTOM bashkit highest bit is 3 or 4
33-123 custom names user highest bit is 5 or 6 but lesser than 124
124-128 E_TIMEOUT - E_INVALID_EXIT bash
129-192 E_SIGHUP - E_SIGRTMAX signal highest bit is 7 low bits for signum
193-254 N/A unused
255 E_OUT_OF_RANGE bash

The queried error list is printed on stdout.

error::list always returns 0 unless invoked with a bad errclass.

EXAMPLE

$ error::list | column -t -s "="
E_SUCCESS            0
E_FAILURE            1
...
E_SIGRTMAX           192

SEE ALSO

error::class(1), error::custom(1), error::whatis(1)

error::whatis

error::whatis - bidirectional mapper between error codes and names

SYNOPSIS

error::whaits error

DESCRIPTION

With error either a positive integer in range [0-255] or a valid name:

^E_([A-Z1-9]+)((_([A-Z1-9])+)*)$
range names owner note
0-3 E_SUCCESS - E_UNSUPPORTED bash
4-7 N/A unused
8-32 E_BASHKIT - E_CUSTOM bashkit highest bit is 3 or 4
33-123 custom names user highest bit is 5 or 6 but lesser than 124
124-128 E_TIMEOUT - E_INVALID_EXIT bash
129-192 E_SIGHUP - E_SIGRTMAX signal highest bit is 7 low bits for signum
193-254 N/A unused
255 E_OUT_OF_RANGE bash

The queried error code/name is printed on stdout and stored in special variable $__.

error::whatis returns 0 on success >0 otherwise.

EXAMPLES

$ error::whatis 129
E_SIGHUP
$ error::class E_SIGHUP
129

SEE ALSO

error::class, error::custom(1), error::list(1)

alert

alert - display an alert message

SYNOPSIS

alert [message …]

DESCRIPTION

With message a string, alert takes an arbitrary number of message arguments. message can be set in special variable $__ or by calling raise(1).

If $LOGLEVEL is >= 1 beforehand or set at runtime each message argument is displayed on its own.

alert is an errcode handler, it returns previous $? unless a write or assignment error occurs.

EXAMPLES

$ alert
2022-11-07 16:50:12+0100 [alert] bash:1|

$ alert "alert message"
2022-11-07 16:50:14+0100 [alert] bash:1| alert message

$ __='preset error'; false \
|| alert
2022-11-07 16:52:11+0100 [alert] bash:1| preset error

$ false || alert 'failure!'
2022-11-07 16:53:44+0100 [alert] bash:1| failure!

$ false \
  || raise "${E_PARAM_ERR}" 'not good' \
  || alert
2022-11-07 16:59:33+0100 [alert] bash:1| not good

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1), errcode::trap(1), raise(1)

crit

crit - display a critical message

SYNOPSIS

crit [message …]

DESCRIPTION

With message a string, crit takes an arbitrary number of message arguments. message can be set in special variable $__ or by calling raise(1).

If $LOGLEVEL is >= 2 beforehand or set at runtime each message argument is displayed on its own.

crit is an errcode handler, it returns previous $? unless a write or assignment error occurs.

EXAMPLES

$ crit
2022-11-07 16:50:12+0100 [crit] bash:1|

$ crit "crit message"
2022-11-07 16:50:14+0100 [crit] bash:1| crit message

$ __='preset error'; false \
|| crit
2022-11-07 16:52:11+0100 [crit] bash:1| preset error

$ false || crit 'failure!'
2022-11-07 16:53:44+0100 [crit] bash:1| failure!

$ false \
  || raise "${E_PARAM_ERR}" 'not good' \
  || crit
2022-11-07 16:59:33+0100 [crit] bash:1| not good

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1), errcode::trap(1), raise(1)

debug

debug - display a debugging message

SYNOPSIS

debug [message …]

DESCRIPTION

With message a string, debug takes an arbitrary number of message arguments. message can be set in special variable $__.

If $LOGLEVEL is set to 7 beforehand or at runtime each message is displayed on its own.

When $TRACE or $REPORT are set, $LOGLEVEL defaults to 7

debug returns success unless a write or assignment error occurs.

EXAMPLES

$ debug
2022-11-08 00:59:32+0100 [debug] bash:1|

$ debug "debug message"
2022-11-08 01:00:03+0100 [debug] bash:1| debug message

$ __='preset message' && debug
2022-11-08 01:00:57+0100 [debug] bash:1| preset message

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1)

error

error - display an error message

SYNOPSIS

error [message …]

DESCRIPTION

With message a string, error takes an arbitrary number of message arguments. message can be set in special variable $__ or by calling raise(1).

If $LOGLEVEL is >= 3 beforehand or set during runtime each message is displayed on its own.

error is an errcode handler, it returns previous $? unless a write or assignment error occurs.

EXAMPLES

$ error
2022-11-07 16:50:12+0100 [error] bash:1|

$ error "error message"
2022-11-07 16:50:14+0100 [error] bash:1| error message

$ __='preset error'; false \
|| error
2022-11-07 16:52:11+0100 [error] bash:1| preset error

$ false || error 'failure!'
2022-11-07 16:53:44+0100 [error] bash:1| failure!

$ false \
  || raise "${E_PARAM_ERR}" 'not good' \
  || error
2022-11-07 16:59:33+0100 [error] bash:1| not good

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1), errcode::trap(1), raise(1)

fatal

fatal - display a message and panic with an error code

SYNOPSIS

fatal [message …]

DESCRIPTION

With message a string, fatal takes an arbitrary number of message arguments. message can be set in special variable $__ or by calling raise(1).

Each message is always displayed on its own.

fatal is an errcode handler, it returns previous $? unless a write or assignment error occurs. If previous $? is 0, fatal defaults to 1.

EXAMPLES

$ fatal
2022-11-07 16:50:12+0100 [fatal] bash:1|

$ fatal "fatal message"
2022-11-07 16:50:14+0100 [fatal] bash:1| fatal message

$ __='preset fatal'; false \
|| fatal
2022-11-07 16:52:11+0100 [fatal] bash:1| preset fatal

$ false || fatal 'failure!'
2022-11-07 16:53:44+0100 [fatal] bash:1| failure!

$ false \
  || raise "${E_PARAM_ERR}" 'not good' \
  || fatal
2022-11-07 16:59:33+0100 [fatal] bash:1| not good

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1), errcode::trap(1), raise(1)

info

info - display an informational message

SYNOPSIS

info [message …]

DESCRIPTION

With message a string, info takes an arbitrary number of message arguments. message can be set in special variable $__.

If $LOGLEVEL is >= 6 beforehand or set at runtime each message is displayed on its own.

info returns success unless a write or assignment error occurs.

info shadows info(1) the bash info document reader. If you need to use this reader, invoke it with command info.

EXAMPLES

$ info
2022-11-08 00:59:32+0100 [info] bash:1|

$ info "info message"
2022-11-08 01:00:03+0100 [info] bash:1| info message

$ __='preset message' && info
2022-11-08 01:00:57+0100 [info] bash:1| preset message

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1)

for info(1) disambiguation:

builtin command, info(1)

$ command [-pVv] info [arg ...]

logging::level

logging::level - display the current logging level

SYNOPSIS

logging::level

DESCRIPTION

logging::level displays the current script logging level on stdout.

It returns success unless a write or assignment error occurs.

EXAMPLES

$ logging::level
6

ENVIRONMENT

SEE ALSO

logging::setlevel(1)

note

note - display a note message

SYNOPSIS

note [message …]

DESCRIPTION

With message a string, note takes an arbitrary number of message arguments. message can be set in special variable $__.

If $LOGLEVEL is >= 5 beforehand or set at runtime each message is displayed on its own.

note returns success unless a write or assignment error occurs.

EXAMPLES

$ note
2022-11-08 00:59:32+0100 [note] bash:1|

$ note "note message"
2022-11-08 01:00:03+0100 [note] bash:1| note message

$ __='preset message' && note
2022-11-08 01:00:57+0100 [note] bash:1| preset message

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1)

panic

panic - display a message and panic with error code 1

SYNOPSIS

panic [message …]

DESCRIPTION

With message a string, panic takes an arbitrary number of message arguments. message can be set in special variable $__ or by calling raise(1).

Each message is always displayed on its own.

panic is an errcode handler, it returns 1.

EXAMPLES

$ panic
2022-11-07 16:50:12+0100 [panic] bash:1|

$ panic "panic message"
2022-11-07 16:50:14+0100 [panic] bash:1| panic message

$ __='preset panic'; false \
|| panic
2022-11-07 16:52:11+0100 [panic] bash:1| preset panic

$ false || panic 'failure!'
2022-11-07 16:53:44+0100 [panic] bash:1| failure!

$ false \
  || raise "${E_PARAM_ERR}" 'not good' \
  || panic
2022-11-07 16:59:33+0100 [panic] bash:1| not good

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1), errcode::trap(1), raise(1)

logging::setlevel

logging::setlevel - modify the current logging level

SYNOPSIS

logging::setlevel [level]

DESCRIPTION

With level either an integer in [0-7] or a string in: panic | emerg | alert | crit | error | warn | note | info | debug, logging::setlevel sets the current script logging level.

If level is invalid, the logging level defaults to INFO/6.

logging::setlevel returns success.

EXAMPLES

$ logging::setlevel 7
$ logging::setlevel debug

ENVIRONMENT

SEE ALSO

logging::level(1)

warn

warn - display a warn message

SYNOPSIS

warn [message …]

DESCRIPTION

With message a string, warn takes an arbitrary number of message arguments. message can be set in special variable $__.

If $LOGLEVEL is >= 4 beforehand or set at runtime each message is displayed on its own.

warn returns success unless a write or assignment error occurs.

EXAMPLES

$ warn
2022-11-08 00:59:32+0100 [warn] bash:1|

$ warn "warn message"
2022-11-08 01:00:03+0100 [warn] bash:1| warn message

$ __='preset message' && warn
2022-11-08 01:00:57+0100 [warn] bash:1| preset message

ENVIRONMENT

SEE ALSO

logging::level(1), logging::setlevel(1)

trap::callback

trap::callback - hook a command to a signal

SYNOPSIS

trap::callback [[arg] signal_spec …]

DESCRIPTION

trap::callback is a wrapper to bash builtin trap that goes the extra mile of stacking up arg to already hooked up commands.

arg and signal_spec are defined in builtin trap help.

Upon reception of signal_spec, the commands are executed in LIFO order.

EXAMPLE

$ trap::callback "echo goodbye world!" EXIT
goodbye world!

SEE ALSO

builtin trap, cleanup(1)

cleanup

cleanup - hook a command to the EXIT signal

SYNOPSIS

cleanup [arg]

DESCRIPTION

cleanup is a wrapper to bashkit trap::callback on the EXIT signal.

arg is defined in bash builtin trap help.

Upon reception of EXIT, the commands are executed in LIFO order.

EXAMPLES

$ cleanup "echo goodbye world!"
goodbye world!
$ touch /tmp/tmpfile && cleanup 'rm -f /tmp/tmpfile'

SEE ALSO

builtin trap, trap::callback(1)

version::bashkit

version::bashkit - get current bashkit version

SYNOPSIS

version::bashkit [VAR]

DESCRIPTION

The version is stored in special bashkit variable $__ or in $VAR if present.

version::bashkit creates a semver compatible version string in the form compat.date.commit[.branch][.hash].

EXAMPLE

$ version::bashkit && echo "${__}"
1.2210.230

SEE ALSO

version::state(1)

COLOPHON

This page is part of the wuage bashkit framework. Source code and all documentation maybe downloaded from http://bashkit.wuage.org

The doc directory distributed with bashkit contains full documentation.

version::state

version::state - get local bashkit version state

SYNOPSIS

version::state [VAR]

DESCRIPTION

The state is stored in special bashkit variable $__ or in $VAR if present.

version::state outputs a string containing local files version information, and is the input of hash version field see version::bashkit(1).

version::state outputs nothing if local files are not modified.

EXAMPLE

$ version::state && echo "${__}"
changed_version.bash ...

SEE ALSO

version::bashkit(1)

COLOPHON

This page is part of the wuage bashkit framework. Source code and all documentation maybe downloaded from http://bashkit.wuage.org

The doc directory distributed with bashkit contains full documentation.

version::update

version::update - set current bashkit version

SYNOPSIS

version::update

DESCRIPTION

version::update is intended to be used by bashkit developers, it allows updating version.bash with current version informations.

version::update generates values for both version::bashkit(1) and version::state(1).

EXAMPLE

$ version::update

SEE ALSO

version::bashkit(1) version::state(1)

COLOPHON

This page is part of the wuage bashkit framework. Source code and all documentation maybe downloaded from http://bashkit.wuage.org

The doc directory distributed with bashkit contains full documentation.

array::contains

array::contains - test if an array contains a given value

SYNOPSIS

array::contains A x [idx]

DESCRIPTION

With A an array variable, x a value and idx a variable, array::contains test if x exists in A and set idx to x index. If idx is not given, the index is set in special variable $__.

array::contains returns 0 if x in A, >0 otherwise or if an error occurs.

EXAMPLE

$ declare -a ARRAY=( 1 2 3 4 )
$ array::contains ARRAY 2 idx
$ echo $?
0
$ echo "${ARRAY[idx]}"
2

array::inter

array::inter - intersect two arrays

SYNOPSIS

array::inter A B

DESCRIPTION

With A et B array variables, array::inter intersects A and B and set the resulting array in A.

array::inter returns 0 unless wrong arguments or error >0.

EXAMPLE

$ declare -a A=( hello world 1 2 3 4 )
$ declare -a B=( 3 4 5 6 goodbye world )
$ array::inter A B
$ echo "${A[@]}"
3 4 world

array::map

array::map - apply a function to an array elements

SYNOPSIS

array::map A fun

DESCRIPTION

With A an array variable and fun a bash function that transforms $1 and prints the result to stdout, array::map applies fun in place to each elements of A.

array::map returns 0 upon success >0 otherwise.

EXAMPLES

$ declare -a A=( {a..e} )
$ up(){ echo ${1^^}; }
$ array::map A up
$ echo "${A[@]}"
A B C D E

SEE ALSO

array::reduce(1)

array::pick

array::pick - pick a random array element

SYNOPSIS

array::pick A [x]

DESCRIPTION

With A an array variable and x a variable, array::pick sets x to a random element of A. If x is not specified, it defaults to the special variable $__.

array::pick returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( 1 2 3 4 )
$ array::pick A x
$ echo "${x}"
3

array::pop

array::pop - remove the last element from an array

SYNOPSIS

array::pop A [x]

DESCRIPTION

With A an array variable and x a variable, array::pop sets x to the last element from A before removing it. If x is not specified, it defaults to the special variable $__.

array::pop returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( 1 2 3 4 )
$ array::pop A x
$ echo "${A[@]}"
1 2 3
$ echo "${x}"
4

SEE ALSO

array::popi(1)

array::popi

array::popi - remove the ith element from an array

SYNOPSIS

array::popi A i [x]

DESCRIPTION

With A an array variable i an index and x a variable, array::popi sets x to the ith element from A before removing it. If i is negative, the element is removed starting from the end of A. If x is not specified, it defaults to the special variable $__.

array::popi returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( 1 2 3 4 )
$ array::popi A 2 x
$ echo "${A[@]}"
1 2 4
$ echo "${x}"
3

SEE ALSO

array::pop(1), array::shift(1)

array::push

array::push - add one or more elements to the end of an array

SYNOPSIS

array::push A [x …]

DESCRIPTION

With A an array variable x a value, array::push adds x at the end of A.

array::push returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {1..11} )
$ array::push A 12
$ echo "${A[-1]}"
12

array::reduce

array::reduce - perform a summary operation of an array

SYNOPSIS

array::reduce A fun acc

DESCRIPTION

With A an array variable, fun a bash function that aggregates $1 and $2 and prints the result to stdout and acc a variable, array::reduce sumarizes A into acc by repetitively aplying fun acc x for x in A.

array::reduce returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {1..8} )
$ add() { echo $(( $1 + $2 )); }
$ acc=0
$ array::reduce A add acc
$ echo "${acc}"
36

SEE ALSO

array::map(1)

array::reverse

array::reverse - reverse an array in place

SYNOPSIS

array::reverse A

DESCRIPTION

With A an array variable, array::reverse reverses A in place.

array::reverse returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {1..11} )
$ array::reverse A
$ echo "${A[@]}"
11 10 9 8 7 6 5 4 3 2 1

array::rotate

array::rotate - shift elements of an array to the specified positions

SYNOPSIS

array::rotate A i

DESCRIPTION

With A an array variable and i an integer, array::rotate shifts elements of A to the specified positions. If i is positive, cycling is done from right to left, if i is negative, cycling occurs from left to right.

array::rotate returns 0 upon success, >0 otherwise.

EXAMPLES

$ declare -a A=( {1..8} )
$ array::rotate A -10
$ echo "${A[@]}"
3 4 5 6 7 8 1 2

array::shift

array::shift - remove the first element of an array

SYNOPSIS

array::shift A [x]

DESCRIPTION

With A an array variable and x a variable, array::shift removes the first element of A and sets x to it. If x is not given, it defaults to special variable $__.

array::shift returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {1..8} )
$ array::shift A x
$ (( x == 1 )) && echo "${A[@]}"
2 3 4 5 6 7 8

SEE ALSO

array::popi(1)

array::shuffle

array::shuffle - randomly reorder elements of an array

SYNOPSIS

array::shuffle A

DESCRIPTION

With A an array variable, array::shuffle performs in place a modern fisher-yates shuffling.

array::shuffle returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {1..8} )
$ array::shuffle A
$ echo "${A[@]}"
7 6 2 1 3 4 5 8

SEE ALSO

https://en.wikipedia.org/wiki/Fisher–Yates_shuffle#Modern_method

array::sort

array::sort - sort elements of an array in place

SYNOPSIS

array::sort A

DESCRIPTION

With A an array variable, array::sort in place sorts the array.

array::sort returns 0 upon success, >0 otherwise.

EXAMPLES

$ declare -a A=( 8 7 5 6 3 4 1 2 )
$ array::sort A
$ echo "${A[@]}"
1 2 3 4 5 6 7 8

array::split

array::split - build an array from a split string

SYNOPSIS

array::split A str sep

DESCRIPTION

With A an array variable, str and sep two strings, array::split divides str into an ordered list of substrings by searching for sep, puts these substrings in A.

array::split returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A
$ array::split A 'apples,oranges,pears,grapes' ','
$ echo "${A[@]}"
apples oranges pears grapes

array::uniq

array::uniq - deduplicate elements of an array

SYNOPSIS

array::uniq A

DESCRIPTION

With A an array variable, array:uniq deduplicates elements in place.

array::uniq returns 0 upon success, >0 otherwise.

EXAMPLES

$ declare -a A=( {1..8} )
$ A+=( "${A[@]}" )  # duplicate array items
$ echo "${A[@]}"
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
$ array::uniq A
$ echo "${A[@]}"
1 2 3 4 5 6 7 8

array::unshift

array::unshift - add one or more elements to the beginning of an array

SYNOPSIS

array::unshift A [x …]

DESCRIPTION

With A an array variable and a list of values x, array::unshift adds them to the beginning of A

array::unshift returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -a A=( {4..8} )
$ array::unshift A 1 2 3
$ echo "${A[@]}"
1 2 3 4 5 6 7 8

array::zip

array::zip - merge two arrays in a dictionary

SYNOPSIS

array::zip D K V

DESCRIPTION

With D an dictionary (ie. associative array), K and V two arrays, array::zip merges the arrays into a dict where keys are taken from K ans associated to values taken in turn from V.

array::zip returns 0 upon success, >0 otherwise.

EXAMPLE

$ declare -A D
$ declare -a K=( {a..e} )
$ declare -a V=( {1..8} )
$ array::zip D K V
$ declare -p D
D=([e]="5" [d]="4" [c]="3" [b]="2" [a]="1" )

check::cmd

check::cmd - check if a command is available

SYNOPSIS

check::cmd [cmd …]

DESCRIPTION

With a list of cmd, check::cmd verify that cmd is executable.

check::cmd returns 0 if cmd is executable, >0 otherwise.

EXAMPLE

$ check::cmd ls cat && echo "ls and cat are available"
ls and cat are available

check::dir

check::dir - ensure a directory exists

SYNOPSIS

check::dir [dir …]

DESCRIPTION

With dir a directory, check::dir ensures that it exists, if not it creates it.

check::dir returns 0 if dir exists or has been created, >0 otherwise.

EXAMPLE

$ check::dir /usr /tmp/mydir

check::vartype

check::vartype - check variable attributes

SYNOPSIS

check::vartype attrs var

DESCRIPTION

With attrs an attribute string and var a variable, check::vartype checks if var has set attrs. It does NOT check the content of var.

Some attrs are inherited from builtin declare:

attr description
a indexed array
A dictionary
i integer
l lower case
n nameref
r readonly
t trace
u upper case
x export

to which bashkit adds:

attr description
f function
s set

A var can be set to an empty value. When checking for a nameref and more, var is dereferenced before checking for more attrs than n.

check::vartype returns 0 upon success, >0 otherwise.

EXAMPLES

$ declare -a ARR=()
$ declare -n _A=ARR
$ check::vartype nas _A && echo OK
OK
$ n=0  # no integer attribute
$ check::vartype i n || echo NOK
NOK

SEE ALSO

builtin declare

curl::download

curl::download - download a file from an URL and print stats

SYNOPSIS

curl::download url dest

DESCRIPTION

With dest being a filename, curl::download prints a downloading digest that contains the size and md5 hash of the downloaded file.

In baskhit, curl hence curl::download are preset with: | option | value | |—————–|——-| | connect-timeout | 5 | | continue-at | - | | fail | | | location | | | retry | 5 | | retry-delay | 0 | | retry-max-time | 40 | | show-error | | | silent | |

curl::download returns 0 upon success, >0 otherwise.

EXAMPLE

$ curl::download http://example.com "${tmpfile}"

SEE ALSO

curl(1)

funlist

funlist - list all declared functions

SYNOPSIS

funlist

DESCRIPTION

funlist is part of bashkit module extras, it lists all declared functions by the time of calling.

EXAMPLE

  $ funlist
  __unhandled
  alert
  bashkit::help
  bashkit::init
  bashkit::load
  bashkit::main
  ...

isint

isint - test for integers

SYNOPSIS

isint [x …]

DESCRIPTION

isint is part of bashkit module extras, given x a value, it tests if x is an integer.

isint returns 0 if all x are integers, >0 otherwise.

EXAMPLE

  $ n=10
  $ isint "${n}" 1 2 3 4 || echo yes
  $ yes

join

join - build a string of arguments separated by a given character

SYNOPSIS

join sep arg [arg …]

DESCRIPTION

join is part of bashkit module extras, given sep a single character and arg a list of arbitrary strings, it builds a string with all args separated by sep.

EXAMPLES

  $ join "," a b c d
  a,b,c,d
  $ join ":" a
  a

now

now - get the number of milliseconds elapsed since EPOCH

SYNOPSIS

now [dest]

DESCRIPTION

now is part of bashkit module extras, it sets dest var to the number of milliseconds elapsed since EPOCH. If dest is omitted, now sets the special variable $__.

EXAMPLE

  $ now start
  $ sleep 1
  $ now end
  $ echo $(( end - start ))
  1008

progress

progress - display a progress bar

SYNOPSIS

progress percent total

DESCRIPTION

progress is part of bashkit module extras, given two integers percent and total, it displays a progress bar. This bar has a len of total dashes.

EXAMPLE

  $ for (( i=0; i<=100; i++ )); do
  >   usleep 5
  >   progress "${i}" 20
  > done
  > printf '\n'
  [--------------------]

urldecode

urldecode - percent decode a string

SYNOPSIS

urldecode url

DESCRIPTION

urldecode is part of bashkit module extras, given a percent-encoded url, it restores it to its original form.

urldecode returns 0 upon success, >0 otherwise.

EXAMPLE

$ urldecode "https%3A%2F%2Fgithub.com%2Fdylanaraps%2Fpure-bash-bible"
https://github.com/dylanaraps/pure-bash-bible

SEE ALSO

urlencode(1)

urlencode

urlencode - percent encode a string

SYNOPSIS

urlencode url

DESCRIPTION

urlencode is part of bashkit module extras, given an url string, it displays a percent encoded version of it.

urlencode returns 0 upon success, >0 otherwise.

EXAMPLE

$ urlencode "https://github.com/dylanaraps/pure-bash-bible"
https%3A%2F%2Fgithub.com%2Fdylanaraps%2Fpure-bash-bible

SEE ALSO

urldecode(1)

usleep

usleep - micro sleep

SYNOPSIS

usleep [n]

DESCRIPTION

usleep is part of bashkit module extras, it waits for a delay proportional to n. When n is omitted, it defaults to 1.

EXAMPLE

$ usleep 10

interactive::yesno

interactive::yesno - ask a yes/no question to the user

SYNOPSIS

interactive::yesno question [default]

DESCRIPTION

interactive::yesno displays question and wait for the user to answer, if default is given, it is used if the user simply presses ENTER.

interactive::yesno returns 0 when user answers yes, >0 otherwise

EXAMPLE

$ interactive::yesno "are you happy?" y
are you happy? [YES/no]:

json::from_toml

json::from_toml - convert toml to json

SYNOPSIS

json::from_toml toml

DESCRIPTION

Given a toml string, json::from_toml converts it to JSON.

json::from_toml returns 0 upon success, >0 otherwise.

SEE ALSO

json::to_toml(1)

json::from_yaml

json::from_yaml - convert yaml to json

SYNOPSIS

json::from_yaml yaml

DESCRIPTION

Given a yaml string, json::from_yaml converts it to json.

json::from_yaml returns 0 upon success, >0 otherwise.

SEE ALSO

json::to_yaml(1)

json::into_array

json::into_array - load a json array into a bash array

SYNOPSIS

json::into_array A jarr

DESCRIPTION

With A an array variable and jarr a string representing a json array, json::into_array loads jarr content into A.

json::into_array returns 0 upon success, >0 otherwise.

EXAMPLE

$ json='["a", "b", 3, 7]'
$ declare -a A
$ json::into_array A <<< "${json}"
$ echo "${A[@]}"
a b 3 7

SEE ALSO

json::into_dict(1)

json::into_dict

json::into_dict - load a json dictionary into a bash one

SYNOPSIS

json::into_dict D jdict

DESCRIPTION

With D an associative array variable and jdict a json dictionary, json::into_dict loads jdict content into D. It does NOT recurse because bash does not support nested dictionaries.

json::into_dict returns 0 upon success, >0 otherwise.

EXAMPLE

$ json='{"a": 3, "7": { "sub": [3, true, "x"] }}'
$ declare -A D
$ json::into_dict D <<< "${json}"
$ echo "${!D[@]}
a 7
$ echo "${D[7]}"
{ "sub": [3, true, "x"] }

SEE ALSO

json::into_array(1)

json::to_toml

json::to_toml - convert json to toml

SYNOPSIS

json::to_toml fd

DESCRIPTION

With fd a file descriptor, json::to_toml reads json from fd and prints the resulting toml to stdout.

json::to_toml returns 0 upon success, >0 otherwise.

EXAMPLE

$ printf '%s\n' "${json}" | json::to_toml /dev/stdin

SEE ALSO

json::from_toml(1)

json::to_yaml

json::to_yaml - convert json to toml

SYNOPSIS

json::to_yaml fd

DESCRIPTION

With fd a file descriptor, json::to_yaml reads json from fd and prints the resulting yaml to stdout.

json::to_yaml returns 0 upon success, >0 otherwise.

EXAMPLE

$ printf '%s\n' "${json}" | json::to_yaml /dev/stdin

SEE ALSO

json::from_yaml(1)

patch::apply

patch::apply - apply a patch

SYNOPSIS

patch::apply dir patch

DESCRIPTION

Witn dir a destination directory and patch a patch file, patch::apply applies modification from patch to dir files.

patch::apply returns 0 upon success, >0 otherwise.

EXAMPLE

$ patch::apply "${DIR}" "a.patch"

SEE ALSO

diff(1), patch(1), patch::batch(1)

patch::batch

patch::batch - apply all patches from a patch directory onto files in a target directory

SYNOPSIS

patch::batch target patches

DESCRIPTION

Witn target a destination directory and patches a patch directory, patch::batch applies modification from patches to target files.

patch::batch returns 0 upon success, >0 otherwise.

EXAMPLE

$ patch::batch "${TARGET_DIR}" "${PATCH_DIR}"

SEE ALSO

diff(1), patch(1), patch::apply(1)

perms::gid

perms::gid - convert group name to gid

SYNOPSIS

perms::gid group

DESCRIPTION

With group a group name as given by id -g, perms::gid converts it to a gid integer as given by id -gn.

perms::gid returns 0 upon success, >0 and logs an error otherwise.

EXAMPLE

$ perms::gid wheel
0

SEE ALSO

id(1), perms::uid(1)

perms::mode

perms::mode - convert symbolic file mode to absolute notation

SYNOPSIS

perms::mode mode

DESCRIPTION

With mode an absolute mode as defined in chmod(1), perms::mode convert it to its absolute representation.

perms::mode returns 0 upon success, >0 otherwise.

EXAMPLE

$ perms::mode "-rw-r--r--"
0644

SEE ALSO

chmod(1)

perms::uid

perms::uid - convert user name to uid

SYNOPSIS

perms::uid user

DESCRIPTION

With user a user name as given by id -u, perms::uid converts it to an uid integer as given by id -un.

perms::uid returns 0 upon success, >0 and logs an error otherwise.

EXAMPLE

$ perms::uid root
0

SEE ALSO

id(1), perms::gid(1)

readlinkf

readlinkf - display symbolic link target status

SYNOPSIS

readlinkf filelink

DESCRIPTION

With filelink a symbolic link, readlinkf resolves paths and displays the corresponding absolute pathname.

readlinkf returns 0 upon success, >0 otherwise.

SEE ALSO

readlink(1), https://github.com/ko1nksm/readlinkf

shopt::pop

shopt::pop - restores previous shopt context

SYNOPSIS

shopt::pop

DESCRIPTION

shopt::pop restores a builtin shopt context previously created by calling shopt::push(1).

shopt::pop always succeeds and returns 0.

EXAMPLE

$ shopt::push
$ shopt -s extdebug
$ do_something_with_extdebug_on
$ shopt::pop

SEE ALSO

builtin shopt, shopt::push(1)

shopt::push

shopt::push - create a new shopt context

SYNOPSIS

shopt::push

DESCRIPTION

shopt::push creates a new shopt context that can be modified and discarded later by a call to shopt::pop(1).

shopt::push always succeeds and returns 0.

EXAMPLE

$ shopt::push
$ shopt -s extdebug
$ do_something_with_extdebug_on
$ shopt::pop

SEE ALSO

builtin shopt, shopt::push(1)

string::lstrip

string::lstrip - remove pattern from start of string

SYNOPSIS

string::lstrip str pat

DESCRIPTION

With str and pat two strings, string::lstrip removes pat occuring at str start (or left side).

EXAMPLES

$ string::lstrip 'The Quick Brown Fox' 'The '
Quick Brown Fox

SEE ALSO

string::rstrip(1), string::strip(1), string::stripall(1)

string::regex

string::regex - match string against regular expression

SYNOPSIS

string::regex str rex

DESCRIPTION

With str and rex two strings, string::regex matches str again regular expression rex and displays the matching part of str.

string::regex returns 0 upon match, >0 otherwise.

EXAMPLE

$ string::regex '    hello' '^[[:space:]]*(.*)'
hello

string::rstrip

string::rstrip - remove pattern from end of string

SYNOPSIS

string::rstrip str pat

DESCRIPTION

With str and pat two strings, string::rstrip removes pat occuring at str end (or right side).

EXAMPLE

$ string::rstrip 'The Quick Brown Fox' ' Fox'
The Quick Brown

SEE ALSO

string::lstrip(1), string::strip(1), string::stripall(1)

string::split

string::split - extract substrings delimited by a separator from string

SYNOPSIS

string::split str sep

DESCRIPTION

With str and sep, two strings, string::split splits str on sep occurences.

EXAMPLE

$ string::split 'apples,oranges,pears,grapes' ','
apples oranges pears grapes

string::strip

string::strip - remove first occuring pattern from string

SYNOPSIS

string::strip str pat

DESCRIPTION

With str and pat two strings, string::strip removes the first occurence of pat in str.

EXAMPLE

$ string::strip 'The Quick Brown Fox' '[aeiou]'
Th Quick Brown Fox

SEE ALSO

string::stripall(1), string::lstrip(1), string::rstrip(1)

string::stripall

string::stripall - remove pattern from string

SYNOPSIS

string::stripall str pat

DESCRIPTION

With str and pat two strings, string::stripall removes all occurences of pat in str.

EXAMPLE

$ string::strip 'The Quick Brown Fox' '[aeiou]'
Th Quck Brwn Fx

SEE ALSO

string::strip(1), string::lstrip(1), string::rstrip(1)

string::trim

string::trim - remove leadind and trailing spaces from string

SYNOPSIS

string::trim str

DESCRIPTION

string::trim removes all leading and trailing spaces from string str.

EXAMPLE

$ string::trim ’ Hello, world ’ Hello, world

semver::compare

semver::compare - compare two semantic version strings and return the result

SYNOPSIS

semver::compare [V1] [V2]

DESCRIPTION

semver::compare compares two semantic version strings, V1 and V2, and returns the result in the form of an integer.

The comparison result is stored in the variable __. A value of 0 indicates that the input strings are equal, a value of 1 indicates that the first input string is greater than the second input string, and a value of -1 indicates that the first input string is less than the second input string.

EXAMPLE

$ semver::compare "1.2.3-alpha.1+build.42" "1.2.3-beta.1+build.42"
$ echo "${__}"  # output: -1

semver::parse

semver::parse - parse a semantic version string and return major, minor, patch, pre-release, and build information

SYNOPSIS

semver::parse [string]

DESCRIPTION

semver::parse parses a semantic version string and returns major, minor, patch, pre-release, and build information. The input string must be in the format of “X.Y.Z(-PRERELEASE)(+BUILD)”. The function checks the input string against a regular expression to ensure the proper format. If the input string does not match the format, the function raises an error. The returned information is stored in __, with the following elements:

${__[0]} - major version
${__[1]} - minor version
${__[2]} - patch version
${__[3]} - pre-release version
${__[4]} - build version

EXAMPLE

$ semver::parse "v1.2.3-alpha.1+build.42"
$ echo "${__[0]}"  # output: 1
$ echo "${__[3]}"  # output: alpha.1