Skip to content

all

L_lib.sh

globals

some global variables

$L_LIB_VERSION

Version of the library

$L_LIB_SCRIPT

The location of L_lib.sh file

$L_NAME

The basename part of $0.

$L_DIR

The directory part of $0.

colors

Variables storing xterm ANSI escape sequences for colors.

Variables with L_ANSI_ prefix are constant. Variables without L_ANSI_ prefix are set or empty depending on L_color_detect function. TheL_color_detect` function can be used to detect if the terminal and user wishes to have output with colors.

Example

echo "$L_RED""hello world""$L_RESET"

$L_BOLD

$L_BRIGHT

$L_DIM

$L_FAINT

$L_ITALIC

$L_STANDOUT

Standaout means italic font.

$L_UNDERLINE

$L_REVERSE

$L_CONCEAL

$L_HIDDEN

$L_CROSSEDOUT

$L_FONT0

$L_FONT1

$L_FONT2

$L_FONT3

$L_FONT4

$L_FONT5

$L_FONT6

$L_FONT7

$L_FONT8

$L_FONT9

$L_FRAKTUR

$L_DOUBLE_UNDERLINE

$L_NODIM

$L_NOSTANDOUT

$L_NOUNDERLINE

$L_NOREVERSE

$L_NOHIDDEN

$L_REVEAL

$L_NOCROSSEDOUT

$L_BLACK

$L_RED

$L_GREEN

$L_YELLOW

$L_BLUE

$L_MAGENTA

$L_CYAN

$L_LIGHT_GRAY

$L_DEFAULT

$L_FOREGROUND_DEFAULT

$L_BG_BLACK

$L_BG_BLUE

$L_BG_CYAN

$L_BG_GREEN

$L_BG_LIGHT_GRAY

$L_BG_MAGENTA

$L_BG_RED

$L_BG_YELLOW

$L_FRAMED

$L_ENCIRCLED

$L_OVERLINED

$L_NOENCIRCLED

$L_NOFRAMED

$L_NOOVERLINED

$L_DARK_GRAY

$L_LIGHT_RED

$L_LIGHT_GREEN

$L_LIGHT_YELLOW

$L_LIGHT_BLUE

$L_LIGHT_MAGENTA

$L_LIGHT_CYAN

$L_WHITE

$L_BG_DARK_GRAY

$L_BG_LIGHT_BLUE

$L_BG_LIGHT_CYAN

$L_BG_LIGHT_GREEN

$L_BG_LIGHT_MAGENTA

$L_BG_LIGHT_RED

$L_BG_LIGHT_YELLOW

$L_BG_WHITE

$L_COLORRESET

$L_RESET

L_color_enable

The L_ color variables are set to the ANSI escape sequences.

Arguments: Takes no arguments

L_color_disable

The L_ color variables are set to empty strings.

Arguments: Takes no arguments

L_term_has_color

Detect if colors should be used on the terminal.

Argument: [$1] file descriptor to check, default: 1

Uses environment variables:

  • TERM
  • NO_COLOR

Return: 0 if colors should be used, nonzero otherwise

See: https://no-color.org/

L_color_detect

Detect if colors should be used on the terminal.

Argument: [$1] file descriptor to check, default 1

Shellcheck disable= SC2120

See: https://en.wikipedia.org/wiki/ANSI_escape_code#Unix_environment_variables_relating_to_color_support

$L_ANSI_BOLD

$L_ANSI_BRIGHT

$L_ANSI_DIM

$L_ANSI_FAINT

$L_ANSI_STANDOUT

$L_ANSI_UNDERLINE

$L_ANSI_REVERSE

$L_ANSI_CONCEAL

$L_ANSI_HIDDEN

$L_ANSI_CROSSEDOUT

$L_ANSI_FONT0

$L_ANSI_FONT1

$L_ANSI_FONT2

$L_ANSI_FONT3

$L_ANSI_FONT4

$L_ANSI_FONT5

$L_ANSI_FONT6

$L_ANSI_FONT7

$L_ANSI_FONT8

$L_ANSI_FONT9

$L_ANSI_FRAKTUR

$L_ANSI_DOUBLE_UNDERLINE

$L_ANSI_NODIM

$L_ANSI_NOSTANDOUT

$L_ANSI_NOUNDERLINE

$L_ANSI_NOREVERSE

$L_ANSI_NOHIDDEN

$L_ANSI_REVEAL

$L_ANSI_NOCROSSEDOUT

$L_ANSI_BLACK

$L_ANSI_RED

$L_ANSI_GREEN

$L_ANSI_YELLOW

$L_ANSI_BLUE

$L_ANSI_MAGENTA

$L_ANSI_CYAN

$L_ANSI_LIGHT_GRAY

$L_ANSI_DEFAULT

$L_ANSI_FOREGROUND_DEFAULT

$L_ANSI_BG_BLACK

$L_ANSI_BG_BLUE

$L_ANSI_BG_CYAN

$L_ANSI_BG_GREEN

$L_ANSI_BG_LIGHT_GRAY

$L_ANSI_BG_MAGENTA

$L_ANSI_BG_RED

$L_ANSI_BG_YELLOW

$L_ANSI_FRAMED

$L_ANSI_ENCIRCLED

$L_ANSI_OVERLINED

$L_ANSI_NOENCIRCLED

$L_ANSI_NOFRAMED

$L_ANSI_NOOVERLINED

$L_ANSI_DARK_GRAY

$L_ANSI_LIGHT_RED

$L_ANSI_LIGHT_GREEN

$L_ANSI_LIGHT_YELLOW

$L_ANSI_LIGHT_BLUE

$L_ANSI_LIGHT_MAGENTA

$L_ANSI_LIGHT_CYAN

$L_ANSI_WHITE

$L_ANSI_BG_DARK_GRAY

$L_ANSI_BG_LIGHT_BLUE

$L_ANSI_BG_LIGHT_CYAN

$L_ANSI_BG_LIGHT_GREEN

$L_ANSI_BG_LIGHT_MAGENTA

$L_ANSI_BG_LIGHT_RED

$L_ANSI_BG_LIGHT_YELLOW

$L_ANSI_BG_WHITE

$L_ANSI_COLORRESET

It resets color and font.

$L_ANSI_RESET

ansi

Very basic functions for manipulating cursor position and color.

Note

unstable

L_ansi_up

L_ansi_down

L_ansi_right

L_ansi_left

L_ansi_next_line

L_ansi_prev_line

L_ansi_set_column

L_ansi_set_position

L_ansi_set_title

$L_ANSI_CLEAR_SCREEN_UNTIL_END

$L_ANSI_CLEAR_SCREEN_UNTIL_BEGINNING

$L_ANSI_CLEAR_SCREEN

$L_ANSI_CLEAR_LINE_UNTIL_END

$L_ANSI_CLEAR_LINE_UNTIL_BEGINNING

$L_ANSI_CLEAR_LINE

$L_ANSI_SAVE_POSITION

$L_ANSI_RESTORE_POSITION

L_ansi_print_on_line_above

Move cursor $1 lines above, output second argument, then move cursor $1 lines down.

Arguments:

  • $1 int lines above
  • $2 str to print

L_ansi_8bit_fg

L_ansi_8bit_bg

L_ansi_8bit_fg_rgb

Set foreground color to 8bit RGB

Arguments:

  • $1 red
  • $2 green
  • $3 blue

L_ansi_8bit_bg_rgb

Set foreground color to 8bit RGB

Arguments:

  • $1 red
  • $2 green
  • $3 blue

L_ansi_24bit_fg

Set foreground color to 24bit RGB

Arguments:

  • $1 red
  • $2 green
  • $3 blue

L_ansi_24bit_bg

Set background color to 24bit RGB

Arguments:

  • $1 red
  • $2 green
  • $3 blue

has

Set of integer variables for checking if Bash has specific feature.

$L_BASH_VERSION

Bash version expressed as a hexadecimal integer variable with digits 0xMMIIPP, where MM is major part, II is minor part and PP is patch part of version.

Shellcheck disable= SC2004

$L_HAS_BASH5_3

$L_HAS_BASH5_2

$L_HAS_BASH5_1

$L_HAS_BASH5_0

$L_HAS_BASH4_4

$L_HAS_BASH4_3

$L_HAS_BASH4_2

$L_HAS_BASH4_1

$L_HAS_BASH4_0

$L_HAS_BASH3_2

$L_HAS_BASH3_1

$L_HAS_BASH3_0

$L_HAS_BASH2_5

$L_HAS_BASH2_4

$L_HAS_BASH2_3

$L_HAS_BASH2_2

$L_HAS_BASH2_1

$L_HAS_BASH2_0

$L_HAS_BASH1_14_7

$L_HAS_COMPGEN_V

`compgen' has a new option: -V varname. If supplied, it stores the generated

$L_HAS_NO_FORK_COMMAND_SUBSTITUTION

New form of command substitution: ${ command; } or ${|command;} to capture

$L_HAS_PATSUB_REPLACEMENT

New shell option: patsub_replacement. When enabled, a `&' in the replacement

$L_HAS_k_EXPANSION

There is a new parameter transformation operator: @k. This is like @K, but

$L_HAS_SRANDOM

SRANDOM: a new variable that expands to a 32-bit random number

$L_HAS_UuLK_EXPASIONS

New U',u', and `L' parameter transformations to convert to uppercas New `K' parameter transformation to display associative arrays as key-

$L_HAS_QEPAa_EXPANSIONS

There is a new ${parameter@spec} family of operators to transform the value of `parameter'.

$L_HAS_LOCAL_DASH

Bash 4.4 introduced function scoped local -

$L_HAS_MAPFILE_D

The `mapfile' builtin now has a -d option

$L_HAS_DECLARE_WITH_NO_QUOTES

The declare builtin no longer displays array variables using the compound

assignment syntax with quotes; that will generate warnings when re-used as input, and isn't necessary. Declare -p on Bash<4.4 adds extra $'\001' before $'\001' and $'\177' bytes.

$L_HAS_NAMEREF

Bash 4.3 introduced declare -n nameref

$L_HAS_PRINTF_T

The printf builtin has a new %(fmt)T specifier

$L_HAS_VARIABLE_FD

If the optional left-hand-side of a redirection is of the form {var},

$L_HAS_EXTGLOB_IN_TESTTEST

Force extglob on temporarily when parsing the pattern argument to

the == and != operators to the [[ command, for compatibility.

$L_HAS_TEST_V

Bash 4.1 introduced test/[/[[ -v variable unary operator

$L_HAS_PRINTF_V_ARRAY

`printf -v' can now assign values to array indices.

$L_HAS_ASSOCIATIVE_ARRAY

Bash 4.0 introduced declare -A var=([a]=b)

$L_HAS_MAPFILE

Bash 4.0 introduced mapfile

$L_HAS_READARRAY

Bash 4.0 introduced readarray

$L_HAS_CASE_FALLTHROUGH

Bash 4.0 introduced case fallthrough ;& and ;;&

$L_HAS_LOWERCASE_UPPERCASE_EXPANSION

Bash 4.0 introduced ${var,,} and ${var^^} expansions

$L_HAS_BASHPID

Bash 4.0 introduced BASHPID variable

$L_HAS_COPROC

Bash 3.2 introduced coproc

$L_HAS_UNQUOTED_REGEX

[[ =~ has to be quoted or not, no one knows.

Bash4.0 change: The shell now has the notion of a compatibility level', controlled by new variables settable byshopt'. Setting this variable currently restores the bash-3.1 behavior when processing quoted strings on the rhs of the =~' operator to the[[' command. Bash3.2 change: Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.

$L_HAS_PREFIX_EXPANSION

Bash 2.4 introduced ${!prefix*} expansion

$L_HAS_HERE_STRING

Bash 2.05 introduced <<<"string"

$L_HAS_INDIRECT_EXPANSION

Bash 2.0 introduced ${!var} expansion

$L_HAS_ARRAY

Bash 1.14.7 introduced arrays

Bash 1.14.7 also introduced: New variables: DIRSTACK, PIPESTATUS, BASH_VERSINFO, HOSTNAME, SHELLOPTS, MACHTYPE. The first three are array variables.

stdlib

Some base simple definitions for every occasion.

L_panic

Print stacktrace, the message and exit.

Example

test -r file || L_panic "File does not exist"

Argument: $1 Message to print.

See:

L_assert

Assert the command starting from second arguments returns success.

Note: [[ is a bash syntax sugar and is not a command. You could use eval "[[ ${var@Q} = ${var@Q} ]]". However to prevent quoting issues it is simpler to use wrapper functions. The function L_regex_match L_glob_match L_not are useful for writing assertions. To invert the test use L_not which just executes ! "$@". ! is not a standalone command or builtin, so it can't be used with this function.

Example

  L_assert 'wrong number of arguments' [ "$#" -eq 0 ]
  L_assert 'first argument must be equal to insert' test "$1" = "insert
  L_assert 'var has to match regex' L_regex_match "$var" ".*test.*"
  L_assert 'var has to not match regex' L_not L_regex_match "$var" "[yY][eE][sS]"
  L_assert 'var has to matcha glob' L_glob_match "$var" "*glob*"

Arguments:

  • $1 str assertiong string description
  • $@ command to test

L_die

Print the arguments to standard error and exit wtih 248.

Example

test -r file || L_die "File is not readable"

See:

L_exit

If argument is not given or an empty string, then exit with 0.

If arguments are not an empty string, print the message to standard error and exit with 247.

Example

    err=()
    test -r file || err+=("file is not readable")
    test -f file || err+=("file is not a file")
    L_exit "${err[@]}"

See:

L_check

If command fails, print a message and exit with 1.

Check L_assert for more info. The difference is, L_assert prints the error message and stacktrace on error. Thid function only prints the error message with program name on error.

See:

L_assert_return

Assert the command starting from second arguments returns success.

If assertion fails, return 249.

See: L_assert

L_regex_match

Wrapper around =~ for contexts that require a function.

Arguments:

  • $1 string to match
  • $2 regex to match against

L_regex_escape

Produce a string that is a regex escaped version of the input.

Option: -v <var> variable to set

Argument: $@ string to escape

L_regex_escape_v

L_regex_findall

Get all matches of a regex to an array.

Option: -v <var> variable to set

Arguments:

  • $1 string to match
  • $2 regex to match

L_regex_findall_v

L_regex_replace

Replace all matches of a regex with a string.

In a string replace all occurences of a regex with replacement string. Backreferences like \& \1 \2 etc. are replaced in replacement string unless -B option is used. Written pure in Bash. Uses [[ =~ operator in a loop.

Example

  L_regex_replace -v out 'world world' 'w[^ ]*' 'hello'
  echo "$out"

Options:

  • -v <var> Variable to set
  • -g Global replace
  • -c <int> Limit count of replacements, default: 1
  • -n <var> Variable to set with count of replacements made.
  • -B Do not handle backreferences in replacement string \& \1 \2 \

Arguments:

  • $1 string to match
  • $2 regex to match
  • $3 replacement string

Exit: If -n option is given, exit with 0, otherwise exit with 0 if at least one replacement was made, otherwise exit with 1.

L_not

inverts exit status

Argument: $@ Command to execute

L_return

Return the first argument

Argument: $1 <int> integer to return

L_setx

Runs the command under set -x.

Argument: $@ Command to execute

L_unsetx

Runs the command under set +x.

Argument: $@ Command to execute

See: L_setx

L_glob_match

Wrapper around == for contexts that require a function.

Arguments:

  • $1 string to match
  • $2 glob to match against

Shellcheck disable= SC2053

See: L_extglob_match

L_extglob_match

Wrapper around == for contexts that require a function.

This is equal to L_glob_match when == has always extglob enabled. However, this was not the case for older bash. In which case this function temporary enables extglob.

Arguments:

  • $1 string to match
  • $2 glob to match against

Shellcheck disable= SC2053

See: L_glob_match

L_glob_escape

Produce a string that is a glob escaped version of the input.

Option: -v <var> variable to set

Argument: $@ string to escape

L_glob_escape_v

L_function_exists

Return 0 if the argument is a function

Argument: $1 function name

L_command_exists

Return 0 if the argument is a command.

Consider using L_hash instead. This differs from L_hash in the presence of an alias. command -v detects aliases. hash detects actual executables in PATH and bash functions.

Argument: $@ commands names to check

See: L_hash

L_hash

Execute Bash hash builtin with silenced output.

A typical mnemonic to check if a command exists is if hash awk 2>/dev/null. This saves to type the redirection.

Why hash and not command or type? Bash stores all executed commands from PATH in hash. Indexing it here, makes the next call faster.

Argument: $@ commands to check

See: L_command_exists

L_is_main

Return 0 if current script is not sourced.

L_is_sourced

Return 0 if current script sourced.

Comparing BASH_SOURCE to $0 only works, when BASH_SOURCE is different from $0. When calling . or source builtin it will be added as an "source" into FUNCNAME array. This function returns false, if there exists a source elemtn in FUNCNAME array.

L_has_sourced_arguments

Return true if sourced script was passed any arguments.

When you source a script and do not pass any arguments, the arguments are equal to the parent scope.

$ set -- a b c ; source <(echo 'echo "$@"')          # script sourced with no arguments
a b c
$ set -- a b c ; source <(echo 'echo "$@"') d e f    # script sourced with arguments
d e f

It is hard to detect if the script arguments are real arguments passed to source command or not. This function detect the case.

Example

   if L_is_main; then
      main
      exit $?
   elif L_has_sourced_arguments; then
      sourced_main "$@"
      return "$?"
   else
      sourced_main
      return "$?"
   fi

Arguments: Takes no arguments

See:

L_is_in_bash

Return 0 if running in bash shell.

Portable with POSIX shell.

L_in_posix_mode

Return 0 if running in posix mode.

L_var_is_set

Return 0 if variable is set

Argument: $1 variable nameref

Exit: 0 if variable is set, nonzero otherwise

L_var_is_notnull

Return 0 if variable is set and is not null (not empty)

Argument: $1 variable nameref

Exit: 0 if variable is set, nonzero otherwise

L_var_is_notarray

Return 0 if variable is not set or is not an array neither an associative array

Argument: $1 variable nameref

L_var_is_array

Success if variable is an indexed integer array, not an associative array.

Argument: $1 variable nameref

Exit: 0 if variable is an array, nonzero otherwise

L_var_is_associative

Return 0 if variable is an associative array

Argument: $1 variable nameref

L_var_is_readonly

Return 0 if variable is readonly

Argument: $1 variable nameref

L_var_is_integer

Return 0 if variable has integer attribute set

Argument: $1 variable nameref

L_var_is_exported

Return 0 if variable is exported.

Argument: $1 variable nameref

L_raise

Send signal to itself

Argument: $1 signal to send, see kill -l

L_handle_v_scalar

Wrapper function for handling -v arguments to other functions.

It calls a function called <caller>_v with arguments, but without -v <var>. The function <caller>_v should set the variable nameref L_v to the returned value. When the caller function is called without -v, the value of L_v is printed to stdout with a newline. Otherwise, the value is a nameref to user requested variable and nothing is printed.

The fucntion L_handle_v_scalar handles only scalar value of L_v or 0-th index of L_v array. To assign an array, prefer L_handle_v_array.

:

   L_hello() { L_handle_v_arr "$@"; }
   L_hello_v() { L_v="hello world"; }
   L_hello          # outputs 'hello world'
   L_hello -v var   # assigns var="hello world"

Option: -v <var> variable to set

Argument: $@ arbitrary function arguments

Shellcheck disable= SC2317

Exit: Whatever exitcode does the <caller>_v funtion exits with.

See: L_handle_v_array

L_handle_v_array

Version of L_handle_v_scalar for arrays.

The options and arguments and exitcode is the same as L_handle_v_scalar.

This additionally supports assignment to arrays. This is not possible with L_handle_v_scalar.

The function L_handle_v_scalar is slightly faster and uses printf -v to assign the result. On newer Bash, printf -v can assign to array and associative arrays variable indexes.

In constract, L_handle_v_array has to first assert if the string is a valid variable name. Only then it uses eval with an array assignment syntax to assign the result to the user requsted variable.

Currently array indexes are not preserved. This could be worked on in the future when needed.

:

   L_hello() { L_handle_v_arr "$@"; }
   L_hello_v() { L_v=(hello world); }
   L_hello          # outputs two lines 'hello' and 'world'
   L_hello -v var   # assigns var=(hello world)

Shellcheck disable= SC2317

See: L_handle_v_scalar.

L_printf_append

Append to the first argument if first argument is not null.

If first argument is an empty string, print the line. Used by functions optically taking a -v argument or printing to stdout, when such functions want to append the printf output to a variable for example in a loop or similar.

Example

   func() {
      if [[ "$1" == -v ]]; then
         var=$2
         shift 2
    fi
    L_printf_append "$var" "%s" "Hello "
    L_printf_append "$var" "%s" "world\n"
 }
 func
 func -v var

Arguments:

  • $1 variable to append to or empty string
  • $2 printf format specification
  • $@ printf arguments

Shellcheck disable= SC2059

L_kill_all_jobs

L_wait_all_jobs

$L_NICE

An array to execute a command nicest way possible.

Example

"${L_NICE[@]}" make -j $(nproc)

L_nice

execute a command in nicest possible way

Argument: $@ command to execute

L_sudo

Execute a command with sudo if not root, otherwise just execute the command.

Preserves all proxy environment variables.

exit_to

L_exit_to

store exit status of a command to a variable

Arguments:

  • $1 variable
  • $@ command to execute

L_exit_to_1null

convert exit code to the word yes or to nothing

Example

    L_exit_to_1null suceeded test "$#" = 0
    echo "${suceeded:+"SUCCESS"}"  # prints SUCCESS or nothing

Arguments:

  • $1 variable
  • $@ command to execute

L_exit_to_1unset

convert exit code to the word yes or to unset variable

Example

    L_exit_to_1null suceeded test "$#" = 0
    echo "${suceeded:+"SUCCESS"}"  # prints SUCCESS or nothing

Arguments:

  • $1 variable
  • $@ command to execute

L_exit_to_10

store 1 if command exited with 0, store 0 if command exited with nonzero

Arguments:

  • $1 variable
  • $@ command to execute

path

L_basename

The filename

Option: -v <var> var

Argument: $1 path

L_basename_v

L_dirname

parent of the path

Option: -v <var> var

Argument: $1 path

L_dirname_v

L_extension

The last dot-separated portion of the final component, if any.

Option: -v <var> var

Argument: $1 path

See: https://en.cppreference.com/w/cpp/filesystem/path/extension.html

L_extension_v

L_extensions

A list of the path’s suffixes, often called file extensions.

Option: -v <var> var

Argument: $1 path

See: https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffixes

L_extensions_v

L_stem

The final path component, without its suffix:

Option: -v <var> var

Argument: $1 path

See: https://en.cppreference.com/w/cpp/filesystem/path/stem

L_stem_v

L_is_absolute

Return whether the path is absolute or not.

L_normalize_path

Replace multiple slashes by one slash.

Option: -v <var> var

Argument: $1 path

L_normalize_path_v

Shellcheck disable= SC2064

L_relative_to

Compute a version of the original path relative to the path represented by other path.

Option: -v <var> var

Arguments:

  • $1 original path
  • $2 other path

See:

L_relative_to_v

Shellcheck disable= SC2179

L_path_append

Append a path to path variable if not already there.

Example

L_path_append PATH ~/.local/bin

Arguments:

  • $1 Variable name. For example PATH
  • $2 Path to append. For example /usr/bin
  • [$3] Optional path separator. Default: ':'

L_path_prepend

Prepend a path to path variable is not already there.

Example

L_path_append PATH ~/.local/bin

Arguments:

  • $1 Variable name. For example PATH
  • $2 Path to prepend. For example /usr/bin
  • [$3] Optional path separator. Default: ':'

L_path_remove

Remove a path from a path variable.

Example

L_path_append PATH ~/.local/bin

Arguments:

  • $1 Variable name. For example PATH
  • $2 Path to prepend. For example /usr/bin
  • [$3] Optional path separator. Default: ':'

string

Collection of functions to manipulate strings.

L_is_true

Return 0 if the string happend to be something like true.

Return 0 when argument is case-insensitive: - true - 1 - yes - y - t - any number except 0 - the character '+'

Argument: $1 str

L_is_false

Return 0 if the string happend to be something like false.

Return 0 when argument is case-insensitive: - false - 0 - no - F - n - the character minus '-'

Argument: $1 str

L_is_true_locale

Return 0 if the string happend to be something like true in locale.

Argument: $1 str

L_is_false_locale

Return 0 if the string happend to be something like false in locale.

Argument: $1 str

L_isprint

Return 0 if all characters in string are printable

Argument: $1 string to check

L_isdigit

Return 0 if all string characters are digits

Argument: $1 string to check

L_is_valid_variable_name

Return 0 if argument could be a variable name.

This function is used to make sure that eval "$1=" will e correct if L_is_valid_variable_name "$1".

Argument: $1 string to check

See: L_is_valid_variable_or_array_element

L_is_valid_variable_or_array_element

Return 0 if argument could be a variable name or array element.

Example

L_is_valid_variable_or_array_element aa           # true
L_is_valid_variable_or_array_element 'arr[elem]'  # true
L_is_valid_variable_or_array_element 'arr[elem'   # false

Argument: $1 string to check

See: L_is_valid_variable_name

L_is_integer

Return 0 if the string characters is an integer

Argument: $1 string to check

L_is_float

Return 0 if the string characters is a float

Argument: $1 string to check

$L_NL

newline

$L_TAB

tab

$L_SOH

Start of heading

$L_STX

Start of text

$L_EOT

End of Text

$L_EOF

End of transmission

$L_ENQ

Enquiry

$L_ACK

Acknowledge

$L_BEL

Bell

$L_BS

Backspace

$L_HT

Horizontal Tab

$L_LF

Line Feed

$L_VT

Vertical Tab

$L_FF

Form Feed

$L_CR

Carriage Return

$L_SO

Shift Out

$L_SI

Shift In

$L_DLE

Data Link Escape

$L_DC1

Device Control 1

$L_DC2

Device Control 2

$L_DC3

Device Control 3

$L_DC4

Device Control 4

$L_NAK

Negative Acknowledge

$L_SYN

Synchronous Idle

$L_ETB

End of Transmission Block

$L_CAN

Cancel

$L_EM

End of Medium

$L_SUB

Substitute

$L_ESC

Escape

$L_FS

File Separator

$L_GS

Group Separator

$L_RS

Record Separator

$L_US

Unit Separator

$L_DEL

Delete

$L_LBRACE

Left brace character

$L_RBRACE

Right brace character

$L_UUID

Looks random.

$L_ALLCHARS

255 bytes with all possible 255 values

$L_ASCII_LOWERCASE

All lowercase characters a-z

$L_ASCII_UPPERCASE

All uppercase characters A-Z

$L_GPL_LICENSE_NOTICE_3_OR_LATER

The GPL3 or later License notice.

See: https://www.gnu.org/licenses/gpl-howto.en.html#license-notices

$L_FREE_SOFTWARE_NOTICE

notice that the software is a free software.

L_quote_setx

Output a string with the same quotating style as does bash in set -x

Option: -v <var> variable to set

Argument: $@ arguments to quote

L_quote_setx_v

L_quote_printf

Output a string with the same quotating style as does bash with printf

For single argument, just use printf -v var "%q" "$var". Use this for more arguments, like printf -v var "%q " "$@" results in a trailing space.

Option: -v <var> variable to set

Argument: $@ arguments to quote

L_quote_printf_v

L_quote_bin_printf

Output a string with the same quotating style as does /bin/printf

Option: -v <var> variable to set

Argument: $@ arguments to quote

L_quote_bin_printf_v

L_strhash

Convert a string to a number.

Option: -v <var> variable to set

L_strhash_v

L_strhash_bash

Convert a string to a number in pure bash.

Option: -v <var> variable to set

L_strhash_bash_v

L_strstr

Check if string contains substring.

Arguments:

  • $1 string
  • $2 substring

L_strupper

Option: -v <var> variable to set

Argument: $1 String to operate on.

L_strlower

Option: -v <var> variable to set

Argument: $1 String to operate on.

L_capitalize

Capitalize first character of a string.

Option: -v <var> variable to set

Argument: $1 String to operate on

L_uncapitalize

Lowercase first character of a string.

Option: -v <var> variable to set

Argument: $1 String to operate on

L_strip

Remove characters from IFS from begining and end of string

Option: -v <var> variable to set

Arguments:

  • $1 <str> String to operate on.
  • [$2] <str> Optional glob to strip, default is [:space:]

L_strip_v

Shellcheck disable= SC2295

L_lstrip

Remove characters from IFS from begining of string

Option: -v <var> variable to set

Arguments:

  • $1 <str> String to operate on.
  • [$2] <str> Optional glob to strip, default is [:space:]

L_lstrip_v

Shellcheck disable= SC2295

L_rstrip

Remove characters from IFS from begining of string

Option: -v <var> variable to set

Arguments:

  • $1 String to operate on.
  • [$2] <str> Optional glob to strip, default is [:space:]

L_rstrip_v

Shellcheck disable= SC2295

L_list_functions_with_prefix

list functions with prefix

Option: -v <var> variable to set

Argument: $1 prefix

L_list_functions_with_prefix_removed

list functions with prefix and remove the prefix

Option: -v <var> var

Argument: $1 prefix

See: L_list_functions_with_prefix

L_list_functions_with_prefix_removed_v

L_json_escape

Produces a string properly quoted for JSON inclusion

Poor man's jq

Example

   L_json_escape -v tmp "some string"
   echo "{\"key\":$tmp}" | jq .

Option: -v <var> variable to set

See:

L_json_escape_v

L_abbreviation

Choose elements matching prefix.

Option: -v <var> Store the result in the array var.

Arguments:

  • $1 prefix
  • $@ elements

L_abbreviation_v

L_float_cmp

compare two float numbers

The '<=>' operator returns 9 when $1 < $2, 10 when $1 == $2 and 11 when $1 > $2.

Example

   L_float_cmp 123.234 -le 234.345
   echo $?  # outputs 0
   L_exit_to ret L_float_cmp 123.234 -le 234.345
   echo "$ret"  # outputs 0

Arguments:

  • $1 <float> one number
  • $2 <str> operator, one of -lt -le -eq -ne -gt -ge > >= == != <= < <=>
  • $3 <float> second number

L_percent_format

print a string with percent format

A simple implementation of percent formatting in bash using regex and printf.

Example

  name=John
  declare -A age=([John]=42)
  L_percent_format "Hello, %(name)s! You are %(age[John])10s years old.\n"

Option: -v <var> Output variable

Arguments:

  • $1 format string
  • $@ arguments

L_percent_format_v

Shellcheck disable= SC2059

L_fstring

print a string with f-string format

A simple implementation of f-strings in bash using regex and printf.

Example

 name=John
 declare -A age=([John]=42)
 L_fstring 'Hello, {name}! You are {age[John]:10s} years old.\n'

Option: -v <var> Output variable

Argument: $1 format string

L_fstring_v

Shellcheck disable= SC2059

L_hexdump

Convert a string to hex dump.

Option: -v <var> Output variable

L_hexdump_v

L_urlencode

Encode a string in percent encoding.

Option: -v <var> Output variable

L_urlencode_v

L_urldecode

Decode percent encoding.

Option: -v <var> Output variable

L_urldecode_v

L_html_escape

Escape characters for html.

Option: -v <var> Output variable

L_html_escape_v

L_str_replace

Replace multiple characters in a string in order.

Note

I think this should be removed.

Example

L_str_replace -v string "$string" "&" "&amp;" "<" "&lt;"

Option: -v <var> Output variable

Arguments:

  • $1 String to operate on.
  • $2 String to replace.
  • $3 Replacement.
  • $@ String to replace and replacement can be repeated multiple times.

See: L_html_escape

L_str_replace_v

L_str_count

Count the character in string.

Option: -v <var> Output variable

Arguments:

  • $1 String.
  • $2 Character to count in string.

L_str_count_v

array

Operations on various lists, arrays and arguments. L_array_*

L_array_len

Get array length.

Example

L_array_len arr

Option: -v <var> Output variable

Argument: $1 <var array nameref

L_array_len_v

L_array_assign

Set elements of array.

Example

L_array_assign arr 1 2 3

Arguments:

  • $1 <var> array nameref
  • $@ elements to set

L_array_set

Assign element of an array

Example

L_array_assign arr 5 "Hello"

Arguments:

  • $1 <var> array nameref
  • $2 <int> array index
  • $3 <str> value to assign

L_array_append

Append elements to array.

Example

L_array_append arr "Hello" "World"

Arguments:

  • $1 <var> array nameref
  • $@ elements to append

L_array_insert

Insert element at specific position in an array.

This will move all elements from the position to the end of the array.

Example

L_array_insert arr 2 "Hello" "World"

Arguments:

  • $1 <var> array nameref
  • $2 <int> index position
  • $@ elements to append

L_array_pop_front

Remove first array element.

Argument: $1 <var> array nameref

L_array_pop_back

Remove last array element.

Example

L_array_pop_back arr

Argument: $1 <var> array nameref

L_array_is_dense

Return success, if all array elements are in sequence from 0.

Example

if L_array_is_dense arr; then echo "Array is dense"; fi

Argument: $1 <var> array nameref

L_array_prepend

Append elements to the front of the array.

Example

L_array_prepend arr "Hello" "World"

Arguments:

  • $1 <var> array nameref
  • $@ elements to append

L_array_clear

Clear an array.

Example

L_array_clear arr

Argument: $1 <var> array nameref

L_array_extract

Assign array elements to variables in order.

Example

  arr=("Hello" "World")
  L_array_extract arr var1 var2
  echo "$var1"  # prints Hello
  echo "$var2"  # prints World

Arguments:

  • $1 <var> array nameref
  • $@ variables to assign to

L_array_reverse

Reverse elements in an array.

Example

    arr=("world" "Hello")
    L_array_reverse arr
    echo "${arr[@]}"  # prints Hello world

Argument: $1 <var> array nameref

L_array_read

Wrapper for readarray for bash versions that do not have it.

Example

L_array_read arr <file

Options:

  • -d <str> separator to use, default: newline
  • -u <fd> file descriptor to read from
  • -s <int> skip first n lines

Argument: $1 <var> array nameref

L_array_pipe

Pipe an array to a command and then read back into an array.

Example

  arr=("Hello" "World")
  L_array_pipe arr tr '[:upper:]' '[:lower:]'
  echo "${arr[@]}"  # prints hello world

Option: -z Use null byte as separator instead of newline.

Arguments:

  • $1 array nameref
  • $@ command to pipe to

Shellcheck disable= SC2059

L_array_contains

check if array variable contains value

Example

  arr=("Hello" "World")
  L_array_contains arr "Hello"
  echo $?  # prints 0

Arguments:

  • $1 array nameref
  • $2 needle

L_array_filter_eval

Remove elements from array for which expression evaluates to failure.

Example

 arr=("Hello" "World")
 L_array_filter_eval arr '[[ "$1" == "Hello" ]]'
 echo "${arr[@]}"  # prints Hello

Arguments:

  • $1 array nameref
  • $2 expression to evaluate with array element of index L_i and value $1

L_array_join

Join array elements separated with the second argument.

Example

  arr=("Hello" "World")
  L_array_join -v res arr ", "
  echo "$res"  # prints Hello, World

Option: -v <var> Output variable

Arguments:

  • $1 <var> array nameref
  • $2 <str> string to join elements with

See: L_args_join

L_array_join_v

L_array_andjoin

Option: -v <var> Output variable

Argument: $1 <var> array nameref

See: L_args_andjoin

L_array_andjoin_v

L_array_to_string

Serialize an array to string representation.

Option: -v <var> Output variable

Argument: $1 <var> array nameref

See: L_array_from_string

L_array_to_string_v

L_array_from_string

Deserialize an array from string.

Example

  arr=(1 2 3)
  L_array_to_string -v tmp
  L_array_from_string arr2 "$tmp"
  echo "${arr2[@]}"

Arguments:

  • $1 <var> array nameref
  • $2 str result from L_array_to_string

See: L_array_to_string

args

Operations on list of arguments.

L_args_join

Join arguments with separator

Example

  L_args_join -v res ", " "Hello" "World"
  echo "$res"  # prints Hello, World

Option: -v <var> Output variable

Arguments:

  • $1 <str> separator
  • $@ arguments to join

See: L_array_join

L_args_join_v

L_args_andjoin

Join arguments with ", " and last with " and "

Option: -v <var> Output variable

Argument: $@ arguments to join

L_args_andjoin_v

L_args_contain

Check if arguments starting from second contain the first argument.

Example

  L_args_contain "Hello" "Hello" "World"
  echo $?  # prints 0

Arguments:

  • $1 needle
  • $@ heystack

L_args_index

Get index number of argument equal to the first argument.

Example

  L_args_index -v res "World" "Hello" "World"
  echo "$res"  # prints 1

Option: -v <var>

Arguments:

  • $1 needle
  • $@ heystack

L_args_index_v

L_max

return max of arguments

Example

L_max -v max 1 2 3 4

Option: -v <var> var

Argument: $@ int arguments

L_max_v

Sets variable: L_v

Shellcheck disable= SC1105 SC2094 SC2035

L_min

return max of arguments

Example

L_min -v min 1 2 3 4

Option: -v <var> var

Argument: $@ int arguments

L_min_v

Sets variable: L_v

Shellcheck disable= SC1105 SC2094 SC2035

utilities

Various self contained functions that could be separate programs.

L_table

Make a table

Example

    $ L_table -R1-2 "name1 name2 name3" "a b c" "d e f"
    name1 name2 name3
        a     b c
        d     e f

Options:

  • -v <var> variable to set
  • -s <separator> IFS column separator to use
  • -o <str> Output separator to use
  • -R Right align columns with these indexes

Argument: $@ Lines to print, joined and separated by newline.

Shellcheck disable= SC1105 SC2201 SC2102 SC2035 SC2211 SC2283 SC2094

L_parse_range_list

Parse cut range list into an array.

Each LIST is made up of one range, or many ranges separated by commas. Selected input is written in the same order that it is read, and is written exactly once. Each range is one of: N N'th byte, character or field, counted from 1 N- from N'th byte, character or field, to end of line N-M from N'th to M'th (included) byte, character or field -M from first to M'th (included) byte, character or field

Example

    $ L_parse_range_list 100 1-4,3-5
    1
    2
    3
    4
    5
    $ L_parse_range_list -v tmp 100 '1-4 3-5'
    $ echo "${tmp[@]}"
    1 2 3 4 5
    $ if L_args_contain 3 "${tmp[@]}"; then echo "yes"; else echo "no"; fi
    yes
    $ if L_args_contain 7 "${tmp[@]}"; then echo "yes"; else echo "no"; fi
    no

Option: -v <var> variable to set

Arguments:

  • $1 max number of fields
  • $2 list of fields

L_parse_range_list_v

L_pretty_print

Prints values with declare, but array values are on separate lines.

Options:

  • -p <str> Prefix each line with this prefix
  • -v <var> Assign output to the variable.
  • -w <int> Set terminal width. This modifies compact output line wrapping.
  • -n Enable pretty printing nested arrays
  • -C Disable compact output for arrays, i.e. each key is on separate line.

Argument: $@ variable names to pretty print

L_argskeywords

Parse python-like positional and keyword arguments format.

The difference to python is that @ is used instead of *, becuase * triggers filename expansion. An argument -- signifies end of arguments definition and start of arguments to parse.

Example

  range() {
     local start stop step
      L_argskeywords start stop step=1 -- "$@" || return 2
      for ((; start < stop; start += stop)); do echo "$start"; done
  }
  range start=1 stop=6 step=2
  range 1 6

  max() {
     local arg1 arg2 args key
     L_argskeywords arg1 arg2 @args key='' -- "$@" || return 2
     ...
  }
  max 1 2 3 4

  int() {
     local string base
     L_argskeywords string / base=10 -- "$@" || return 2
     ...
  }
  int 10 7 # error
  int 10 base=7

Options:

  • -A <var> Instead of storing in variables, store values in specified associative array with variables as key.
  • -M Use L_map instead of associative array, for @@kwargs and -A option. Usefull for older Bash.
  • -E Exit on error
  • -e <str> Prefix error messages with this prefix. Default: "${FUNCNAME[1]}:L_argskeywords:"

Arguments:

  • $@ Python arguments format specification
  • $2 <str> --
  • $@ Arguments to parse

See:

L_version_cmp

Compare version numbers.

Arguments:

  • $1 str one version
  • $2 str one of: -lt -le -eq -ne -gt -ge '<' '<=' '==' '!=' '>' '>=' '~='
  • $3 str second version
  • [$4] int accuracy, how many at max elements to compare? By default up to 3.

Shellcheck disable= SC2053

See: https://peps.python.org/pep-0440/

log

logging library

This library is meant to be similar to python logging library.

Example

    L_log_set_level ERROR
    L_error "this is an error"
    L_info "this is information"
    L_debug "This is debug"

$L_LOGLEVEL_CRITICAL

$L_LOGLEVEL_ERROR

$L_LOGLEVEL_WARNING

$L_LOGLEVEL_NOTICE

$L_LOGLEVEL_INFO

$L_LOGLEVEL_DEBUG

$L_LOGLEVEL_TRACE

$L_LOGLEVEL_NAMES

convert log level to log name

$L_LOGLEVEL_COLORS

get color associated with particular loglevel

Shellcheck disable= SC2153

$L_logconf_color

1 or ''. Should we use the color for logging output?

L_log_configure

configure L_log system

Example

  L_log_configure \
    -l debug \
    -c 0 \
    -f 'printf -v L_logrecord_msg "%s" "${@:2}"' \
    -o 'printf "%s\n" "$@" >&2' \
    -s 'L_log_select_source_regex ".*/script.sh"'

Options:

  • -h Print help and return 0.
  • -r Allow for reconfiguring L_log system. Otherwise second call of this function is ignored.
  • -l <LOGLEVEL> Set loglevel. Can be \$L_LOGLEVEL_INFO INFO or 30. Default: $_L_logconf_level
  • -c <BOOL> Enable/disable the use of color. Default: $L_logconf_color
  • -f <FORMATEVAL> Evaluate expression for formatting. Default: $_L_logconf_formateval
  • -s <SELECTEVAL> If eval "SELECTEVAL" exits with nonzero, do not print the line. Default: $_L_logconf_selecteval
  • -o <OUTPUTEVAL> Evaluate expression for outputting. Default: $_L_logconf_outputeval

Arguments: Takes no arguments

L_log_level_inc

increase log level

Argument: $1 <int> amount, default: 10

L_log_level_dec

decrease log level

Argument: $1 <int> amount, default: 10

$L_logrecord_stacklevel

int positive stack level to omit when printing caller information

Example

    echo \
     "${BASH_SOURCE[L_logrecord_stacklevel]}" \
     "${FUNCNAME[L_logrecord_stacklevel]}" \
     "${BASH_LINENO[L_logrecord_stacklevel]}"

$L_logrecord_loglevel

int current log line log level

Example

    printf "%sHello%s\n" \
      "${L_logconf_color:+${L_LOGLEVEL_COLORS[L_logrecord_loglevel]:-}}" \
      "${L_logconf_color:+$L_COLORRESET}"

L_log_stack_inc

increase stacklevel of logging information

Arguments: Takes no arguments

See: L_fatal implementation

L_log_stack_dec

decrease stacklevel of logging information

Example

  func() {
      L_log_stack_inc
      trap L_log_stack_dec RETURN
      L_info hello world
  }

Arguments: Takes no arguments

L_log_level_to_int

Convert log string to number

Arguments:

  • $1 str variable name
  • $2 int|str loglevel like INFO info or 30

L_log_is_enabled_for

Check if loggin is enabled for specified level

Argument: $1 str|int loglevel or log string

Sets variable: L_logrecord_loglevel

Uses environment variable: _L_logconf_level

L_log_select_source_regex

Finction that can be passed to filtereval to filter specific bash source name.

Argument: $1 Regex to match against BASH_SOURCE

See: L_log_configure

L_log_select_function_regex

Finction that can be passed to filtereval to filter specific bash source name.

Argument: $1 Regex to match against BASH_SOURCE

See: L_log_configure

L_log_format_default

Default logging formatting

Arguments:

  • $1 str log line printf format string
  • $@ any log line printf arguments

Sets variable: L_logrecord_msg

Uses environment variables:

  • L_logrecord_stacklevel
  • L_logrecord_loglevel
  • L_LOGLEVEL_NAMES
  • L_LOGLEVEL_COLORS
  • BASH_LINENO
  • FUNCNAME
  • L_NAME

See: L_log_configure

L_log_format_long

Format logrecord with timestamp information.

Arguments:

  • $1 str log line printf format string
  • $@ any log line printf arguments

Sets variable: L_logrecord_msg

Uses environment variables:

  • L_logrecord_stacklevel
  • L_logrecord_loglevel
  • L_LOGLEVEL_NAMES
  • L_LOGLEVEL_COLORS
  • BASH_LINENO
  • FUNCNAME
  • L_NAME

See: L_log_configure

L_log_output_to_stderr

Output formatted line to stderr

Argument: $@ message to output

See: L_log_configure

L_log_output_to_logger

Output formatted line with logger

Argument: $@ message to output

Uses environment variables:

  • L_NAME
  • L_logrecord_loglevel
  • L_LOGLEVEL_NAMES

See: L_log_configure

L_log_handle

Handle log message to output

Warning

Users could overwrite this function.

Argument: $@ Log message

Uses environment variables:

  • L_logrecord_loglevel
  • L_logrecord_stacklevel

L_log

main logging entrypoint

Options:

  • -s <int> Increment stacklevel by this much
  • -l loglevel to print log line as

Arguments:

  • $1 str log line printf format string
  • $@ any log line printf arguments

Sets variables:

  • L_logrecord_loglevel
  • L_logrecord_stacklevel

Shellcheck disable= SC2140

L_critical

output a critical message

Option: -s <int> stacklevel increase

Argument: $1 message

L_error

output a error message

Option: -s <int> stacklevel increase

Argument: $1 message

L_warning

output a warning message

Option: -s <int> stacklevel increase

Argument: $1 message

L_notice

output a notice

Option: -s <int> stacklevel increase

Argument: $1 message

L_info

output a information message

Option: -s <int> stacklevel increase

Argument: $1 message

L_debug

output a debugging message

Option: -s <int> stacklevel increase

Argument: $1 message

L_trace

output a tracing message

Option: -s <int> stacklevel increase

Argument: $1 message

L_fatal

Output a critical message and exit the script with 2.

Argument: $@ L_critical arguments

L_logrun

log a command and then execute it

Is not affected by L_dryrun variable.

Argument: $@ command to execute

$L_dryrun

set to 1 if L_run should not execute the function.

L_run

Logs the quoted argument with a leading +. if L_dryrun is nonzero, executes the arguments.

Options:

  • -l <loglevel> Set loglevel
  • -s <stacklevel> Increment stacklevel by this number

Argument: $@ command to execute

Uses environment variable: L_dryrun

sort

Array sorting function.

L_shuf_bash

Shuffle an array

Argument: $1 array nameref

L_shuf_cmd

Shuffle an array using shuf command

Option: -z --zero-terminated use zero separated stream with shuf -z

Arguments:

  • $* any options are forwarded to shuf command
  • $-1 array nameref

L_shuf

Shuffle an array

Argument: $1 array nameref

L_sort_bash

Quicksort an array in place in pure bash.

Options:

  • -z ignored. Always zero sorting
  • -n numeric sort, otherwise lexical
  • -r reverse sort
  • -c <compare> custom compare function that returns 0 when $1 > $2 and 1 otherwise

Argument: $1 array nameref

See: L_sort

L_sort_cmd

Sort an array using sort command.

Even in most optimized code that I could write for bash sorting, still executing sort command is faster. The difference becomes significant for large arrays. Sorting 100 element array with bash is 0.049s and with sort is 0.022s.

Example

   arr=(5 2 5 1)
   L_sort_cmd -n arr
   echo "${arr[@]}"  # 1 2 5 5

Options:

  • -z --zero-terminated use zero separated stream with sort -z
  • -n numeric sort

Arguments:

  • $* any options are forwarded to sort command
  • $-1 last argument is the array nameref

L_sort

Sort a bash array.

If sort command exists, use L_sort_cmd, otherwise use L_sort_bash. If you have a custom sorter, use L_sort_bash, otherwise prefer L_sort_cmd for speed.

Options:

  • -z Use zero separated stream with sort -z
  • -n numeric sort
  • -r reverse sort

Argument: $1 <var> array nameref

See:

trap

L_print_traceback

Prints traceback

:

  Example traceback:
  Traceback from pid 3973390 (most recent call last):
    File ./bin/L_lib.sh, line 2921, in main()
  2921 >> _L_lib_main "$@"
    File ./bin/L_lib.sh, line 2912, in _L_lib_main()
  2912 >>                 "test") _L_lib_run_tests "$@"; ;;
    File ./bin/L_lib.sh, line 2793, in _L_lib_run_tests()
  2793 >>                 "$_L_test"
    File ./bin/L_lib.sh, line 891, in _L_test_other()
  891  >>                 L_unittest_eq "$max" 4
    File ./bin/L_lib.sh, line 1412, in L_unittest_eq()
  1412 >>                 _L_unittest_showdiff "$1" "$2"
    File ./bin/L_lib.sh, line 1391, in _L_unittest_showdiff()
  1391 >>                 sdiff <(cat <<<"$1") - <<<"$2"

Arguments:

  • [$1] int stack offset to start from (default: 0)
  • [$2] int number of lines to show around the line (default: 2)

L_trap_err_small

Callback to be exectued on ERR trap that prints just the caller.

Example

  trap 'L_trap_err_small' ERR

L_trap_err

description Callback to be exectued on ERR trap that prints a traceback and exits.

Example

   trap 'L_trap_err $?' ERR
   trap 'L_trap_err $?' EXIT

Argument: $1 int exit code

L_trap_err_enable

Enable ERR trap with L_trap_err as callback

set -eEo functrace and register trap 'L_trap_err $?' ERR.

Example

 L_trap_err_enable

L_trap_err_disable

Disable ERR trap

Example

  L_trap_err_disable

L_trap_err_init

If set -e is set and ERR trap is not set, enable ERR trap with L_trap_err as callback

Example

   L_trap_err_init

$L_TRAP_RETURN_RESTORE_SHOPT

Create a return trap that restores all shopt options.

Example

  func() {
     eval "$L_TRAP_RETURN_RESTORE_SHOPT"
     shopt -s extglob
     # stuff with extglob
  }

L_trap_to_number

Convert trap name to number

Option: -v <var> var

Argument: $1 trap name or trap number

L_trap_to_number_v

L_trap_to_name

convert trap number to trap name

Example

L_trap_to_name -v var 0 && L_assert '' test "$var" = EXIT

Option: -v <var> var

Argument: $1 signal name or signal number

L_trap_to_name_v

L_trap_get

Get the current value of trap

Example

  trap 'echo hi' EXIT
  L_trap_get -v var EXIT
  L_assert '' test "$var" = 'echo hi'

Option: -v <var> var

Argument: $1 signal name or number

L_trap_get_v

L_trap_push

Suffix a newline and the command to the trap value

Arguments:

  • $1 str command to execute
  • $2 str signal to handle

L_trap_pop

remove a command from trap up until the last newline

Argument: $1 str signal to handle

Shellcheck disable= SC2064

unittest

Testing library

Simple unittesting library that does simple comparison. Testing library for testing if variables are commands are returning as expected.

Note

rather stable

Example

   L_unittest_eq 1 1

$L_unittest_fails

Integer that increases with every failed test.

$L_unittest_exit_on_error

Set this variable to 1 to exit immediately when a test fails.

$L_unittest_unset_x

Set this varaible to 1 to disable set -x inside L_unittest functions, Set to 0 to don't.

L_unittest_main

Get all functions that start with a prefix specified with -P and execute them one by one.

Options:

  • -h help
  • -P <prefix> Get functions with this prefix to test
  • -r <regex> filter tests with regex
  • -E exit on error

L_unittest_checkexit

Check if command exits with specified exitcode.

Arguments:

  • $1 <int> exit code the command should exit with
  • $@ command to execute

Shellcheck disable= SC2035

L_unittest_success

Check if command exits with 0

Argument: $@ command to execute

L_unittest_failure

Check if command exits with non zero

Argument: $@ command to execute

L_unittest_failure_capture

capture stdout and stderr into variables of a failed command

Arguments:

  • $1 var stdout and stderr output
  • $@ command to execute

L_unittest_cmd

Test execution of a command and capture and test it's stdout and/or stderr output.

Local variables used by this function start with _L_u. Options with L_uopt. This function optionally runs the command in the current shell or not depending on options.

Example

  echo Hello world /tmp/1
  L_unittest_cmd -r 'world' grep world /tmp/1
  L_unittest_cmd -r 'No such file or directory' ! grep something not_existing_file

Options:

  • -h Print this help and exit.
  • -c Run in current execution environment, instead of using a subshell.
  • -i Invert exit status. You can also use ! or L_not in front of the command.
  • -I Do not close stdin <&1 . By default it is closed.
  • -f Expect the command to fail. Equal to -i -j -N.
  • -N Redirect stdout of the command to >/dev/null.
  • -j Redirect stderr to stdout of the command. 2>&1
  • -x Run the command inside set -x
  • -X Do not modify set -x
  • -v <var> Capture stdout of the command into this variable. Use -j to capture also stderr.
  • -r <regex> Compare output of the command with this regex.
  • -o <str> Compare output of the command with this string.
  • -e <int> Command should exit with this exit status (default: 0)

Argument: $@

Command to execute.

If a command starts with !, this implies -i and, if one of -v -r -o option is used, it implies -j.

L_unittest_vareq

Test if a variable has specific value.

Arguments:

  • $1 variable nameref
  • $2 value

L_unittest_eq

Test if two strings are equal.

Arguments:

  • $1 one string
  • $2 second string

L_unittest_arreq

Test if array is equal to elements.

Arguments:

  • $1 array variable
  • $@ values

L_unittest_ne

Test two strings are not equal.

Arguments:

  • $1 one string
  • $2 second string

L_unittest_regex

test if a string matches regex

Arguments:

  • $1 string
  • $2 regex

L_unittest_contains

Test if a string contains other string.

Arguments:

  • $1 string
  • $2 needle

map

Key value store without associative array support

L_map consist of an null initial value. L_map stores keys and values separated by a tab, with an empty leading newline. Value is qouted by printf %q . Map key may not contain newline or tab characters.

                # empty initial newline
key<TAB>$'value'
key2<TAB>$'value2' # no trailing newline

This format matches the regexes used in L_map_get for easy extraction using bash variable substitution. The map depends on printf %q never outputting a newline or a tab character, instead using $'\t\n' form.

L_map_init

Initializes a map

Example

   local var
   L_map_init var

Argument: $1 var variable name holding the map

L_map_clear

Clear a map

Argument: $1 var variable name holding the map

L_map_remove

Clear a key of a map

Example

    L_map_init var
    L_map_set var a 1
    L_map_remove var a
    if L_map_has var a; then
      echo "a is set"
    else
      echo "a is not set"
    fi

Arguments:

  • $1 var map
  • $2 str key

L_map_set

Set a key in a map to value

Example

  L_map_init var
  L_map_set var a 1
  L_map_set var b 2

Arguments:

  • $1 var map
  • $2 str key
  • $3 str value

L_map_get

Assigns the value of key in map.

If the key is not set, then assigns default if given and returns with 1. You want to prefer this version of L_map_get

Example

   L_map_init var
   L_map_set var a 1
   L_map_get -v tmp var a
   echo "$tmp"  # outputs: 1

Option: -v <var> var

Arguments:

  • $1 var map
  • $2 str key
  • [$3] str default

L_map_get_v

L_map_has

Example

    L_map_init var
    L_map_set var a 1
    if L_map_has var a; then
      echo "a is set"
    fi

Arguments:

  • $1 var map
  • $2 str key

Exit: 0 if map contains key, nonzero otherwise

L_map_setdefault

set value of a map if not set

Arguments:

  • $1 var map
  • $2 str key
  • $3 str default value

L_map_append

Append value to an existing key in map

Arguments:

  • $1 var map
  • $2 str key
  • $3 str value to append

L_map_keys

List all keys in the map.

Example

  L_map_init var
  L_map_set var a 1
  L_map_set var b 2
  L_map_keys -v tmp var
  echo "${tmp[@]}"  # outputs: 'a b'

Option: -v <var> variable to set

Argument: $1 var map

L_map_keys_v

L_map_values

List all values in the map.

Example

   L_map_init var
   L_map_set var a 1
   L_map_set var b 2
   L_map_values -v tmp var
   echo "${tmp[@]}"  # outputs: '1 2'

Option: -v <var> variable to set

Argument: $1 var map

L_map_values_v

L_map_items

List items on newline separated key value pairs.

Example

  L_map_init var
  L_map_set var a 1
  L_map_set var b 2
  L_map_items -v tmp var
  echo "${tmp[@]}"  # outputs: 'a 1 b 2'

Option: -v <var> variable to set

Argument: $1 var map

L_map_items_v

L_map_load

Load all keys to variables with the name of $prefix$key.

Example

    L_map_init var
    L_map_set var a 1
    L_map_set var b 2
    L_map_load var PREFIX_
    echo "$PREFIX_a $PREFIX_b"  # outputs: 1 2

Arguments:

  • $1 map variable
  • $2 prefix
  • $@ Optional list of keys to load. If not set, all are loaded.

L_map_save

Save all variables with prefix to a map.

Example

   L_map_init var
   PREFIX_a=1
   PREFIX_b=2
   L_map_save var PREFIX_
   L_map_items -v tmp var
   echo "${tmp[@]}"  # outputs: 'a 1 b 2'

Arguments:

  • $1 map variable
  • $2 prefix

asa

collection of function to work on associative array

Note

unstable

L_asa_copy

Copy associative dictionary.

Notice: the destination array is not cleared. Slowish, O(N). Iterates of keys one by one

Arguments:

  • $1 var Source associative array
  • $2 var Destination associative array
  • [$3] str Filter only keys with this regex

See: L_asa_copy

L_asa_has

check if associative array has key

Arguments:

  • $1 associative array nameref
  • $2 key

L_asa_is_empty

check if associative array is empty

Argument: $1 associative array nameref

L_asa_get

Get value from associative array

Option: -v <var> var

Arguments:

  • $1 associative array nameref
  • $2 key
  • [$3] optional default value

Exit: 1 if no key found and no default value

L_asa_get_v

L_asa_len

get the length of associative array

Option: -v <var> var

Argument: $1 associative array nameref

L_asa_len_v

L_asa_keys_sorted

get keys of an associative array in a sorted

Option: -v <var> var

Argument: $1 associative array nameref

L_asa_keys_sorted_v

L_asa_set

assign value to associative array

You might think why this function exists? In case you have associative array name in a variable.

Example

   local -A map
   printf -v "map[a]" "%s" val  # will fail in bash 4.0
   L_asa_set map a val  # will work in bash4.0

Arguments:

  • $1 <var> assoatiative array variable
  • $2 <str> key to assign to
  • $3 <str> value to assign

L_asa_from_declare

Extract associative array from string

Example

   declare -A map=([a]=b [c]=d)
   declare string=""
   string=$(declare -p "map")
   declare -A mapcopy=()
   L_asa_from_declare mapcopy = "${string}"

Arguments:

  • $1 var associative array nameref to store
  • $2 =
  • $3 var source variable nameref

See:

L_asa_assign

Copy associative dictionary

Notice: the destination array is cleared. Much faster then L_asa_copy. Note: Arguments are in different order.

Example

  local -A map=([a]=b [c]=d)
  local -A mapcopy=()
  L_asa_assign mapcopy = map

Arguments:

  • $1 var Destination associative array
  • $2 =
  • $3 var Source associative array

See:

argparse

argument parsing in bash

L_argparse_fatal

Print argument parsing error and exit.

Uses environment variables:

  • L_NAME
  • _L_parser

Exit: 1

L_argparse_print_help

Print help or only usage for given parser or global parser.

Syntax:

Usage: prog_name cmd1 cmd2 [-abcd] [+abcd] [--option1] [-o ARG] arg
                                                                ^^^  - _L_args_usage
                                           ^^^^^^^^^^^^^^^^^^^^      - _L_options_usage
                           ^^^^^^^ ^^^^^^                            - _L_options_usage_noargs
       ^^^^^^^^^^^^^^^^^^^                                           - _L_prog
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  - usage string
Options:
  -o --option ARG     Help message
                      ^^^^^^^^^^^^   - help message
  ^^^^^^^^^^^^^^^                    - name
  ^^^^^^^^^^^^^^^$'\n'^^^^^^^^^^^    - _L_usage_args_helps _L_usage_cmds_helps _L_options_helps

Option: -s --short print only usage, not full help

Shellcheck disable= SC2120

L_argparse_print_usage

Print usage.

Shellcheck disable= SC2120

$L_argparse_template_help

Add -h --help option

Example

L_argparse -- "${L_argparse_template_help[@]}" ---- "$@"

See: L_argparse_template_verbose

$L_argparse_template_verbose

Add -v --verbose option that increases log level

Example

L_argparse -- "${L_argparse_template_verbose[@]}" ---- "$@"

See: L_argparse_template_quiet

$L_argparse_template_quiet

Add -q --quiet options that decreses log level

Example

L_argparse -- "${L_argparse_template_quiet[@]}" ---- "$@"

See: L_argparse_template_dryrun

$L_argparse_template_dryrun

Add -n --dryrun argument to argparse.

Example

L_argparse -- "${_L_argparse_template_dryrun[@]}" ---- "$@"

See: L_argparse_template_help

L_argparse_validator

Validate arguments inside validator for argparse.

In case of validation error, prints the error message.

Arguments:

  • $1 <str> error message
  • $2 <str> value to validate
  • $@ <str> command to execute for validation

Exit: 1 if validation fails

See: _L_argparse_validator_int

L_argparse_compgen

Run compgen that outputs correctly formatted completion stream.

With option description prefixed with the 'plain' prefix. Any compgen option is accepted, arguments are forwarded to compgen.

Options:

  • --ANY Any options supported by compgen, except -P and -S
  • -D <str> Specify the description of appended to the result. If description is an empty string, it is not printed. Default: help of the option.

Argument: $1 <str> incomplete

Exit: 0 if compgen returned 0 or 1, otherwise 2

L_argparse

Parse command line aruments according to specification.

This command takes groups of command line arguments separated by -- with sentinel ---- . The first group of arguments are arguments _L_parser. The next group of arguments are arguments _L_optspec. The last group of arguments are command line arguments passed to _L_argparse_parse_args.

Note

the last separator ---- is different to make it more clear and restrict parsing better.

proc

Allows to open multiple processes connected via pipe.

L_is_fd_open

Check if file descriptor is open.

Argument: $1 file descriptor

Shellcheck disable= SC2188

L_get_free_fd

Get free file descriptors

Argument: $@ variables to assign with the file descriptor numbers

L_pipe

Open two connected file descriptors.

This intenrally creates a temporary file with mkfifo The result variable is assigned an array that: - [0] element is input from the pipe, - [1] element is the output to the pipe. This is meant to mimic the pipe() C function.

Arguments:

  • $1 <var> variable name to assign result to
  • $2 <str> template temporary filename, default: L_pipe_XXXXXXXXXX

Shellcheck disable= SC2094

L_proc_popen

Process open. Coproc replacement.

The input/output options are in three groups:

  • -I and -i for stdin,
  • -O and -o for stdout,
  • -E and -e for stderr.

Uppercase letter option specifies the mode for the file descriptor.

There are following modes available that you can give to uppercase options -I -O and -E:

  • null - redirect to or from /dev/null
  • close - close the file descriptor >&-
  • input - -i specifies the string to forward to stdin. Only allowed for -I.
  • stdout - connect file descriptor to stdout. -o or -e value are ignored.
  • stderr - connect file descriptor to stderr. -o or -e value are ignored.
  • pipe - create a fifo and connect file descriptor to it. -i -o or -e option specifies part of the temporary filename.
  • file - connect file descriptor to file specified by -i -o or -e option
  • fd - connect file descriptor to another file descriptor specified by -i -o or -e option

There first argument specifies an output variable that will be assigned as an array with the following indexes:

  • [0] - if -Ipipe will store the file descriptor connected to stdin of the program, otherwise empty.
  • [1] - if -Opipe will store the file descriptor connected to stdout of the program, otherwise empty.
  • [2] - if -Epipe will store the file descriptor connected to stderr of the program, otherwise empty.
  • [3] - stores the pid of the program.
  • [4] - stores the generated command.
  • [5] - stores exitcode.

You should use getters L_proc_get_* to extract the data from proc array elements.

Example

  L_proc_popen -Ipipe -Opipe proc sed 's/w/W/g'
  L_proc_printf proc "%s\n" "Hello world"
  L_proc_read proc line
  L_proc_wait -c -v exitcode proc
  echo "$line"
  echo "$exitcode"

Options:

  • -I <str> stdin mode
  • -i <str> string for -Iinput, file for -Ifile, fd for -Ifd
  • -O <str> stdout mode
  • -o <str> file for -Ifile, fd for -Ifd
  • -E <str> stderr mode
  • -e <str> file for -Efile, fd for -Efd
  • -p <int> Open a pipe for additional file descriptors. (TODO)
  • -n Dryrun mode. Do not execute the generated command. Instead print it to stdout.

Arguments:

  • $1 variable name to store the result to.
  • $@ command to execute.

L_proc_get_stdin

Get file descriptor for stdin of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_stdin_v

L_proc_get_stdout

Get file descriptor for stdout of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_stdout_v

L_proc_get_stderr

Get file descriptor for stderr of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_stderr_v

L_proc_get_pid

Get PID of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_pid_v

L_proc_get_cmd

Get command of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_cmd_v

L_proc_get_exitcode

Get exitcode of L_proc.

Option: -v <var> variable to set

Argument: $1 L_proc variable

L_proc_get_exitcode_v

L_proc_printf

Write printf formatted string to coproc.

Arguments:

  • $1 L_proc variable
  • $@ any printf arguments

L_proc_read

Exec read bultin with -u file descriptor of stdout of coproc.

Arguments:

  • $1 L_proc variable
  • $@ any builtin read options

L_proc_read_stderr

Exec read bultin with -u file descriptor of stderr of coproc.

Arguments:

  • $1 L_proc variable
  • $@ any builtin read options

See: L_proc_read

L_proc_close

Close stdin, stdout and stderr of L_proc

Argument: $1 L_proc variable

L_proc_close_stdin

Close stdin of L_proc.

Does nothing if already closed or not started with -Opipe.

Argument: $1 L_proc variable

L_proc_close_stdout

Close stdout of L_proc.

Does nothing if already closed or not started with -Opipe

Argument: $1 L_proc variable

L_proc_close_stderr

Close stderr of L_proc.

Does nothing if already closed or not started with -Epipe.

Argument: $1 L_proc variable

L_proc_poll

Check if L_proc is finished.

Argument: $1 L_proc variable

Exit: 0 if L_proc is running, 1 otherwise

L_proc_wait

Wait for L_proc to finish.

If L_proc has already finished execution, will only evaluate -v option.

Options:

  • -t <int> Timeout in seconds. Will try to use waitpid, tail --pid or busy loop with sleep.
  • -v <var> Assign exitcode to this variable.
  • -c Close L_proc file descriptors before waiting.

Argument: $1 L_proc variable

Exit: 0 if L_proc has finished, 1 if timeout expired

L_read_fds

Read from multiple file descriptors at the same time.

Arguments:

  • -t <timeout> Timeout in seconds.
  • -p <timeout> Poll timeout. The read -t argument value. Default: 0.01
  • $1 <int> file descriptor to read from
  • $2 <var> variable to assign the output of
  • $@ Pairs of variables and file descriptors.

L_proc_communicate

Communicate with L_proc.

Options:

  • -i <str> Send string to stdin.
  • -o <var> Assign stdout to this variable.
  • -e <var> Assign stderr to this variable.
  • -t <int> Timeout in seconds.
  • -k Kill L_proc after communication.
  • -v <var> Assign exitcode to this variable.

Argument: $1 L_proc variable

Exit: 0 on success. 2 on invalid options. 128 on timeout when reading output. 130 on timeout when waiting for process to terminate.

L_proc_send_signal

Send signal to L_proc.

Argument: $1 L_proc variable

L_proc_terminate

Terminate L_proc.

Argument: $1 L_proc variable

L_proc_kill

Kill L_proc.

Argument: $1 L_proc variable

lib

internal functions and section.

Internal functions to handle terminal interaction.