Skip to content

These are some functions that I call "basic" because they are really that useful. The create the "base" programming experience and feel I want to expect from a programming language.

The are many functions here that I am not sure how to group correctly. They should be grouped in smaller sections.

Generated section documentation:

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.