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_BLINK
¶
$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_NOBLINK
¶
$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
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_BLINK
¶
$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_NOBLINK
¶
$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:
-
$1int lines above -
$2str to print
L_ansi_8bit_fg
¶
L_ansi_8bit_bg
¶
L_ansi_8bit_fg_rgb
¶
Set foreground color to 8bit RGB
Arguments:
-
$1red -
$2green -
$3blue
L_ansi_8bit_bg_rgb
¶
Set foreground color to 8bit RGB
Arguments:
-
$1red -
$2green -
$3blue
L_ansi_24bit_fg
¶
Set foreground color to 24bit RGB
Arguments:
-
$1red -
$2green -
$3blue
L_ansi_24bit_bg
¶
Set background color to 24bit RGB
Arguments:
-
$1red -
$2green -
$3blue
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_TRAP_P
¶
trap has -P option
$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_WAIT_P
¶
wait: has a new -p VARNAME option, which stores the PID returned by `wait -n'
$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_EPOCHREALTIME
¶
There is an EPOCHREALTIME variable, which expands to the time in seconds
$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_WAIT_N
¶
The wait' builtin has a new-n' option to wait for the next child to
$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.
assert
¶
L_panic
¶
Print stacktrace and the message to stderr and exit with 249.
Example
[[ -r "$file" ]] || L_panic "File is not readable: $file"
Option:
-[0-9]+
Exit with this number.
Argument:
$@
Message to print.
See:
L_assert
¶
Assert the command succeeds.
Execute a command given from the second positional argument.
When the command fails, execute L_panic.
Note: [[ is a bash syntax sugar and is not a command.
! is also not a standalone command or builtin, so it can't be used with this function.
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 ! "$@".
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:
-
$1str Assertion description.
If the description starts with '-[0-9]+', the number is used as the exit code for L_panic.
-
$@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"
Option:
-[0-9]+
Exit with this number.
See:
L_exit
¶
With no arguments or an empty string, exit with 0.
Otherwise, the arguments are printed to stderr and exit with 247.
Note
If you want to exit with number, just call builtin exit,
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
¶
Execute a command given from the second argument.
If the command fails, call L_exit.
The difference to L_assert is that it prints calltrace on error.
L_check function only prints the error message with the program name on error.
See:
func
¶
Function for writing function programs.
L_func_comment
¶
Extract the comment above the function.
By default, get the comment of the calling function.
Example
# some unrelated comment followed by an empty line
# some comment
somefunc() {
L_func_comment
}
somefunc # outputs '# some comment'
L_func_comment -f somefunc
Options:
-
-v <var>Assign result to this variable. -
-f <funcname>Print the comment of given function instead of the calling function. -
-s <int>Consider the calling function this many stackframes above. Default: 0 -
-bUse Bash, do not use sed. For testing. -
-hPrint this help and return 0.
Return: 0 if extracted an non-empty comment above the function definition.
L_func_help
¶
Print function comment as usage message.
:
# @option -t this is an option
# @option -g <arg> this is an option with an argument
# @option -h Print this help and return 0.
# @arg arg This is an argument
utility() {
local OPTIND OPTARG OPTERR opt t g
while getopts tg:h opt; do
case "$opt" in
t) t=1 ;;
g) g=$OPTARG ;;
h) L_func_help; return 0 ;;
*) L_func_usage; return 2 ;;
esac
done
shift "$((OPTARG-1))"
L_func_assert "one positional argument required" test "$#" -eq 1 || return 2
#
: utility logic
}
utility -h # prints the comment above the function
utility -invalid # prints 'Usage: utility [-th] [-g arg] arg'
Argument:
[int]
How many stack frames up.
Return: 0
See:
L_func_usage
¶
Print funtion usage to stderr.
Argument:
[$1]
How many stack frames up.
L_func_error
¶
Print function error to stderr.
Arguments:
-
[$1]Message. -
[$2]How many stack frames up.
See: L_func_help for example
L_func_usage_error
¶
Print function error with usage.
Arguments:
-
[$1]Message. -
[$2]How many stack frames up.
See: L_func_help for example
L_func_assert
¶
Assert that the command exits with 0.
If it does not, call L_func_error and return 2. If the message starts with -[0-9]+, the number is used as the number of stackframes up the message is about.
Example
utility() {
local num="$1"
L_func_assert "not a number: $num" L_is_integer "$num" || return 2
}
Arguments:
-
$1Message to print, may be empty. -
$@Arguments to test.
Return: 2 if the expression failed.
L_func_log
¶
Print a line prefixed by the calling function name.
Argument:
$@
line to print
L_function_copy
¶
Make a copy of a function.
Currently there is no sanitization done in the function. The second argument allows for execution under eval.
Arguments:
-
$1existing function -
$2new function name
L_function_modify
¶
Add a script on the top or the end of a function.
Arguments:
-
$1The function to modify -
$2Script to put in front of the function body. -
$3Script to put on the end of the function body.
L_decorate
¶
Apply a decorator on a function.
The next call on a function will call the decorator with arguments followed by function name with arguments.
Example
func() { echo something; }
print_and_call() {
echo "CALLING: $@" >&2
"$@"
}
func # outputs something
func # outputs something
L_decorate print_and_call func
func # outputs "CALLING func" and then "something"
func # outputs "CALLING func" and then "something"
Example
func() { L_print_traceback; }
L_decorate L_setx func
L_decorate time func
L_decorate L_setx time func
func arg # calls: [L_setx time func arg]
# which calls [time func arg]
# which calls L_setx func arg
Arguments:
-
$@Decorator to apply with arguments. -
$#-1Function.
L_time
¶
Measure time with the command, but include the command in the time message output and use %6l format.
Argument:
$@
command to measure.
L_duration_to_usec
¶
Parse 1w1d1h2m2s into number of microseconds.
Option:
-v <var>
Argument:
$1
Duration string.
See: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#configuration-file
L_duration_to_usec_v
¶
L_cache
¶
Cache the execution of a command.
The command execution is cached in _L_CACHE global variable or in file when -f option is present. The second execution of the command will result in a cached execution. On cached execution the exit status of the command will be extracted from the cache.
Example
L_cache -T 10m -O output -f /tmp/cache.L_cache curl -sS https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
myfunc() {
var=$(( 1 + 2 ))
}
L_decorate L_cache -v var -k myfunc myfunc
myfunc
myfunc
Options:
-
-oCache the stdout of the command.
It will run the command in a process substitution. -
-O <var>Cache the stdout of the command and store it in variable instead of printing.
It will run the command in a process substitution. -
-s <var>Add this variable to the cache. All cache variables will be restored on cached execution. -
-f <file>Use the file as cache.
The file has a header with version number. The file stores internal cache state from declare -p _L_cache variable. The file content is eval-ed upon loading. -
-rInstead of executing, remove the cache entry associated with the command. -
-lInstead of executing, only list the entires in the cache. -
-T <ttl>Set time to live in duration string. Default: infinity. -
-L <01>Lock the file with flock. Default: use flock if available. -
-k <key>Use this key to index the cache. Default: %q quoted command with argumnets. -
-hPrint this help and return 0.
Arguments:
-
$1Command to execute. -
$@Arguments.
Sets variable:
_L_CACHE
Uses environment variable:
_L_CACHE
Shellcheck disable= SC2094
Return:
222 on internal error
otherwise returns the exit status of the cached command.
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>
Store the output in variable instead of printing it.
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.
stdlib
¶
Some base simple definitions for every occasion.
L_regex_match
¶
Wrapper around =~ for contexts that require a function.
Arguments:
-
$1string to match -
$2regex to match against
L_regex_escape
¶
Produce a string that is a regex escaped version of the input.
Works for both basic and extended regular expression.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$@
string to escape
See:
- https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04
- https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03
L_regex_escape_v
¶
L_regex_findall
¶
Get all matches of a regex to an array.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1string to match -
$2regex 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>Store the output in variable instead of printing it. -
-gGlobal replace -
-c <int>Limit count of replacements, default: 1 -
-n <var>Variable to set with count of replacements made. -
-BDo not handle backreferences in replacement string \& \1 \2 \ -
-hPrint this help and return 0.
Arguments:
-
$1string to match -
$2regex to match -
$3replacement 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_execute
¶
Executes the command.
Argument:
$@
Command to execute.
L_not
¶
Inverts exit status.
Argument:
$@
Command to execute.
L_return
¶
Return the first argument
Argument:
$1
L_shopt_extglob
¶
Runs the command with extglob restoring the option after return.
Argument:
$@
Command to execute
L_setx
¶
Runs the command under set -x restoring the setting after return.
Argument:
$@
Command to execute
L_unsetx
¶
Runs the command under set +x restoring the setting after return.
Argument:
$@
Command to execute
See: L_setx
L_setposix
¶
Runs the command under set -o posix restoring the setting after return.
Argument:
$@
Command to execute
L_unsetposix
¶
Runs the command under set +o posix restoring the setting after return.
Argument:
$@
Command to execute
L_glob_match
¶
Wrapper around == for contexts that require a function.
Arguments:
-
$1string to match -
$2glob 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:
-
$1string to match -
$2glob 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>
Store the output in variable instead of printing it.
Argument:
$@
string to escape
L_glob_escape_v
¶
L_source
¶
Execute source with arguments.
This is usefull when wanting to source a script without passing a arguments.
Arguments:
-
$1Script to source. -
$@Positional arguments to script.
Shellcheck disable= SC1090
See: https://stackoverflow.com/a/73791073/9072753
L_eval
¶
Evaluate the expression by first setting the arguments.
This is usefull to properly quote the expression and still use eval and variables.
Example
L_assert 'variable has quotes' L_eval '[[ "$1" != *\"* ]]' "$variable"
# much simpler and easier to quote than:
L_assert 'variable has quotes' "[[ ${variable@Q} == *\\\"* ]]"
Arguments:
-
$1Script to execute. -
$@Positional arguments to set for the duration of the script.
L_subshell
¶
Call the command in a subshell.
Argument:
$@
Command to excute.
L_compgen
¶
Wrapper around compgen that does not support -V argument.
Note
copmgen -W allows execution. For example `compagen -W '$(echo something >&2)'`` executes echo.
Option:
-V <var>
Store the output in variable instead of printing it.
Argument:
$@
Any other compgen options and arguments.
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 element 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 by checking for a command "source" in FUNCNAME.
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:
- https://stackoverflow.com/a/79201438/9072753
- https://stackoverflow.com/questions/61103034/avoid-command-line-arguments-propagation-when-sourcing-bash-script/73791073#73791073
- https://unix.stackexchange.com/questions/568747/bash-builtin-variables-bash-argv-and-bash-argc
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_to_string
¶
Serialize variable value to a string that can be declared.
The result is a string that is the value of variable quoted in a format that can be reused as input to declare.
For scalar variables, the function outputs a quoted value of the variable.
For array and associative array variables, the function outputs
a string in the form of ([a]=b) that can be used to assign to another variable.
Use declare with -a or -A for arrays to load the result into a variable.
Eval is not preferred and might result in in valid values on Bash<4.4.
Bash<4.4 prepends byte 0x01 in front of bytes 0x01 and 0x7f.
Single 0x01 in declare -p output results in double 0x01,0x01.
Example
local -A map=([a]=b [c]=d)
L_var_to_string -v tmp map
declare -A map2=$tmp
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
variable name
See:
L_var_is_notarray
¶
Return 0 if variable is not an array neither an associative array.
Argument:
$1
variable nameref
L_var_is_array
¶
Return 0 if variable is an indexed integer array, not an associative array.
Argument:
$1
variable nameref
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_var_to_string_v
¶
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() {
local var=
if [[ "$1" == -v ]]; then
var=$2
shift 2
fi
L_printf_append "$var" "%s" "Hello "
L_printf_append "$var" "%s" "world\n"
}
func # prints hello world
func -v var # stores hello world in $v
Arguments:
-
$1variable to append to or empty string -
$2printf format specification -
$@printf arguments
Shellcheck disable= SC2059 SC2059
$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_renice
¶
Make the command be nicest possible.
Argument:
[$1]
Pid of the process. Default: $BASHPID.
L_show_nice
¶
Show niceness levels of a process.
Argument:
[$1]
Pid of the process. Default: $BASHPID
L_sudo
¶
Execute a command with sudo if not root, otherwise just execute the command.
Preserves all proxy environment variables.
L_uuid4
¶
Generate uuid in bash.
Option:
-v <var>
Store the output in variable instead of printing it.
See: https://digitalbunker.dev/understanding-how-uuids-are-generated/
L_uuid4_v
¶
L_date
¶
Print date in the format.
If the format string contains %N or the timepoint is not a number, use date command. Otherwise, try to use printf %(fmt)T.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and exit.
Arguments:
-
$1Format string. -
[$2]Optional timepoint.
L_date_v
¶
L_epochrealtime_usec
¶
Return time in microseconds.
The dot or comma is removed from EPOCHREALTIME. Uses EPOCHREALTIME in newer Bash. In older Bash tries GNU date, gdate, perl, /proc/uptime, python, busybox adjtimex.
Option:
-v <var>
L_epochrealtime_usec_v
¶
L_sec_to_usec
¶
Convert float seconds to microseconds.
Example
L_sec_to_usec 1.5 -> 1500000
Option:
-v <var>
L_sec_to_usec_v
¶
L_usec_to_sec
¶
Convert microseconds to seconds with 6 digits after comma.
Option:
-v <var>
L_usec_to_sec_v
¶
L_timeout_set_to
¶
Calculate timeout value.
The timeout value is stored in microseconds.
Note
should this be L_timeout_assign -v ?
Arguments:
-
$1Variable to assign with the timeout value in usec. -
$2Timeout in seconds. May be a fraction.
See: L_epochrealtime_usec
L_timeout_expired
¶
Is the timeout expired?
Argument:
$1
timeout value
L_timeout_left
¶
Get the number of seconds left in the timer.
Option:
-v <var>
Argument:
$1
timeout value
L_timeout_left_v
¶
exit_to
¶
L_exit_to
¶
store exit status of a command to a variable
Arguments:
-
$1variable -
$@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:
-
$1variable -
$@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:
-
$1variable -
$@command to execute
L_exit_to_10
¶
store 1 if command exited with 0, store 0 if command exited with nonzero
Arguments:
-
$1variable -
$@command to execute
path
¶
L_path_basename
¶
The filename
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
L_path_basename_v
¶
L_path_dirname
¶
parent of the path
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
L_path_dirname_v
¶
L_path_extension
¶
The last dot-separated portion of the final component, if any.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
See: https://en.cppreference.com/w/cpp/filesystem/path/extension.html
L_path_extension_v
¶
L_path_extensions
¶
A list of the path’s suffixes, often called file extensions.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
See: https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffixes
L_path_extensions_v
¶
L_path_stem
¶
The final path component, without its suffix:
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
See: https://en.cppreference.com/w/cpp/filesystem/path/stem
L_path_stem_v
¶
L_path_with_name
¶
Return a new path with the name changed.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1path -
$1new name
L_path_with_name_v
¶
L_path_with_stem
¶
Return a new path with the stem changed.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1path -
$2new stem
L_path_with_stem_v
¶
Shellcheck disable= SC2179
L_path_with_suffix
¶
Return a new path with the suffix changed.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1path -
$2new suffix
L_path_with_suffix_v
¶
Shellcheck disable= SC2179
L_path_is_absolute
¶
Return whether the path is absolute or not.
L_path_normalize
¶
Replace multiple slashes by one slash.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
path
L_path_normalize_v
¶
Shellcheck disable= SC2064
L_path_relative_to
¶
Compute a version of the original path relative to the path represented by other path.
This method is string-based.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1original path -
$2other path
See:
- https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.relative_to
- https://stackoverflow.com/a/12498485/9072753
L_path_relative_to_v
¶
Shellcheck disable= SC2179
L_path_is_relative_to
¶
Check if a path is relative to other path.
This method is string-based; it neither accesses the filesystem nor treats “..” segments specially. Consider as alternative: L_path_relative_to -v tmp "$1" "$2" && [[ "$tmp" == ../* ]]
Example
L_path_is_relative_to /etc/passwd /etc # return 0
L_path_is_relative_to /etc/passwd /usr # return 1
Arguments:
-
$1Path to check -
$2Path that $1 should be relative to.
L_path_append
¶
Append a path to path variable if not already there.
Example
L_path_append PATH ~/.local/bin
Arguments:
-
$1Variable name. For example PATH -
$2Path to append. For example /usr/bin -
[$3]Optional path separator. Default: ':'
L_path_prepend
¶
Prepend a path to path variable if not already there.
Example
L_path_append PATH ~/.local/bin
Arguments:
-
$1Variable name. For example PATH -
$2Path 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:
-
$1Variable name. For example PATH -
$2Path to prepend. For example /usr/bin -
[$3]Optional path separator. Default: ':'
L_dir_is_empty
¶
Return 0 if a directory is empty.
Argument:
$1
Directory.
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
L_is_valid_function_name
¶
Is the string a valid Bash opinionated function name?
Almost anything is valid Bash function name.
Argument:
$1
string to check
See:
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.
See: L_uuid4
$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>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
Argument:
$@
arguments to quote
L_quote_bin_printf_v
¶
L_strhash
¶
Convert a string to a number.
Option:
-v <var>
Store the output in variable instead of printing it.
L_strhash_v
¶
L_strhash_bash
¶
Convert a string to a number in pure bash.
Option:
-v <var>
Store the output in variable instead of printing it.
L_strhash_bash_v
¶
L_strstr
¶
Check if string contains substring.
Arguments:
-
$1string -
$2substring
L_strupper
¶
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on.
L_strlower
¶
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on.
L_capitalize
¶
Capitalize first character of a string.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on
L_uncapitalize
¶
Lowercase first character of a string.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
String to operate on
L_strip
¶
Remove characters from IFS from begining and end of string
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]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>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]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>
Store the output in variable instead of printing it.
Arguments:
-
$1String to operate on. -
[$2]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>
Store the output in variable instead of printing it.
Argument:
$1
prefix
L_list_functions_with_prefix_v
¶
L_list_functions_with_prefix_removed
¶
list functions with prefix and remove the prefix
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
prefix
See: L_list_functions_with_prefix
L_list_functions_with_prefix_removed_v
¶
L_abbreviation
¶
Choose elements matching prefix.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1prefix -
$@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:
-
$1one number -
$2operator, one of -lt -le -eq -ne -gt -ge > >= == != <= < <=> -
$3second number
L_float
¶
A simple wrapper script around awk to evaluate float expressions.
Argument:
$1
Expression to evaluate.
L_percent_format
¶
Print a string with percent format.
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"
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1format 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'
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Argument:
$1
format string
L_fstring_v
¶
Shellcheck disable= SC2059
L_hexdump
¶
Convert a string to hex dump.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_hexdump_v
¶
L_urlencode
¶
Encode a string in percent encoding.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_urlencode_v
¶
L_urldecode
¶
Decode percent encoding.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_urldecode_v
¶
L_html_escape
¶
Escape characters for html.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
L_html_escape_v
¶
L_string_replace
¶
Replace multiple characters in a string in order.
Note
I think this should be removed.
Example
L_string_replace -v string "$string" "&" "&" "<" "<"
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1String to operate on. -
$2String to replace. -
$3Replacement. -
$@String to replace and replacement can be repeated multiple times.
See: L_html_escape
L_string_replace_v
¶
L_string_count
¶
Count the character in string.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1String. -
$2Character to count in string.
L_string_count_v
¶
L_string_count_lines
¶
Count lines in a string.
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Argument:
$1
String.
L_string_count_lines_v
¶
L_string_split
¶
Split a string with quotes without the risk of execution anything.
Rules: - https://www.gnu.org/software/bash/manual/html_node/Escape-Character.html - https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html - https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html - https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
Why not xargs? To support ANSI-C quoting style $'' and support newlines in quotes.
Why not declare? Declare allows execution, declare -a array='($(echo something >&2))'executes echo.
Example
$ L_string_split -v cmd "ls -l 'somefile; rm -rf ~'"
$ declare -p cmd
declare -a cmd=([0]="ls" [1]="-l" [2]="somefile; rm -rf ~")
Options:
-
-v <var>Store the output in variable instead of printing it. -
-cEnable comments. -
-ADisable ANSI-C quoting. -
-hPrint this help and return 0.
Shellcheck disable= SC1003
json
¶
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>
Store the output in variable instead of printing it.
See:
- https://ecma-international.org/wp-content/uploads/ECMA-404.pdf figure 5
- https://stackoverflow.com/a/27516892/9072753
L_json_escape_v
¶
L_json_create
¶
Very simple function to create JSON.
Every second argument is quoted for JSON, unless This argument is preceeded by a previous argument ending with ] or }, when the counter starts over.
Example
L_json_make { \
a : b , \
b :[ 1 , 2 , 3 , 4 ] \
c :[true, 1 ,null,false] \
}
# ^^^^^^ ^^^^^^^^^^^^ - unquoted, added literally to the string
# outputs: {"a":"b","b":[1,2,3,4],"c":[true,"1",false,null]}
array
¶
Operations on various lists, arrays and arguments. L_array_*
L_array_len
¶
Get array length.
Example
L_array_len arr
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
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:
-
$1array nameref -
$@elements to set
L_array_set
¶
Assign element of an array
Example
L_array_assign arr 5 "Hello"
Arguments:
-
$1array nameref -
$2array index -
$3value to assign
L_array_append
¶
Append elements to array.
Example
L_array_append arr "Hello" "World"
Arguments:
-
$1array 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:
-
$1array nameref -
$2index position -
$@elements to append
L_array_pop_front
¶
Remove first array element.
Argument:
$1
array nameref
L_array_pop_back
¶
Remove last array element.
Example
L_array_pop_back arr
Argument:
$1
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
array nameref
L_array_prepend
¶
Append elements to the front of the array.
Example
L_array_prepend arr "Hello" "World"
Arguments:
-
$1array nameref -
$@elements to append
L_array_clear
¶
Clear an array.
Example
L_array_clear arr
Argument:
$1
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:
-
$1array 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
array nameref
L_readarray
¶
Wrapper for readarray for bash versions that do not have it.
Example
L_readarray arr <file
Options:
-
-d <delim>separator to use, default: newline -
-u <fd>file descriptor to read from -
-s <count>skip first n lines -
-hPrint this help and return 0.
Argument:
$1
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:
-
$1array 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:
-
$1array nameref -
$2needle
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:
-
$1array nameref -
$2expression toevaluate with array element of index L_i and value $1
L_array_index
¶
Find an index of an element in the array equal to second argument.
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1array nameref -
$2element to find
L_array_index_v
¶
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
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Arguments:
-
$1array nameref -
$2string to join elements with
See: L_args_join
L_array_join_v
¶
L_array_andjoin
¶
Options:
-
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Argument:
$1
array nameref
See: L_args_andjoin
L_array_andjoin_v
¶
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>
Store the output in variable instead of printing it.
Arguments:
-
$1separator -
$@arguments to join
See: L_array_join
L_args_join_v
¶
L_args_andjoin
¶
Join arguments with ", " and last with " and "
Option:
-v <var>
Store the output in variable instead of printing it.
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:
-
$1needle -
$@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:
-
$1needle -
$@heystack
L_args_index_v
¶
L_max
¶
return max of arguments
Example
L_max -v max 1 2 3 4
Option:
-v <var>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
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>Store the output in variable instead of printing it. -
-s <separator>IFS column separator to use. Default: space or tab. -
-o <str>Output separator to use -
-R <list[int]>Right align columns with these indexes -
-hPrint this help and return 0.
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>
Store the output in variable instead of printing it.
Arguments:
-
$1max number of fields -
$2list 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>Store the output in variable instead of printing it. -
-w <int>Set terminal width. This modifies compact output line wrapping. -
-nEnable pretty printing nested arrays -
-CDisable compact output for arrays, i.e. each key is on separate line. -
-hPrint this help and return 0.
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. -
-MUse L_map instead of associative array, for @@kwargs and -A option. Usefull for older Bash. -
-EExit on error -
-e <str>Prefix error messages with this prefix. Default: "${FUNCNAME[1]}:L_argskeywords:" -
-hPrint this help and return 0.
Arguments:
-
$@Python arguments format specification -
$2-- -
$@Arguments to parse
See:
- https://docs.python.org/3/reference/compound_stmts.html#function-definitions
- https://realpython.com/python-asterisk-and-slash-special-parameters/
L_version_cmp
¶
Compare version numbers.
Arguments:
-
$1str one version -
$2str one of: -lt -le -eq -ne -gt -ge '<' '<=' '==' '!=' '>' '>=' '~=' -
$3str 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.
was log system configured?
_L_logconf_configured=0
int current global log level
_L_logconf_level=$L_LOGLEVEL_INFO
1 or 0 or ''. Should we use the color for logging output?
_L_logconf_color=
if this regex is set, allow elements
_L_logconf_selecteval=
default formatting function
_L_logconf_formateval='L_log_format_default "$@"'
default outputting function
_L_logconf_outputeval=L_log_output_to_stderr
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_log_configure
¶
Configure L_log module.
Example
L_log_configure \
-l debug \
-c 0 \
-f 'printf -v L_logline "${@:2}"' \
-o 'printf "%s\n" "$L_logline" >&2' \
-s '[[ $L_logline_source == */script.sh ]]'
Options:
-
-hPrint this help and return 0. -
-rAllow for reconfiguring L_log system. Otherwise the next call of this function is ignored. -
-l <LOGLEVEL>Set loglevel. Can be \$L_LOGLEVEL_INFO INFO or 30. Default: $_L_logconf_level -
-c <BOOL>Set to 1 to enable the use of color, set to 0 to disable the use of color.
Set to '' empty string to detect if stdout has color support. Default: '' -
-f <FORMATEVAL>Evaluate expression for formatting. Default: 'L_log_format_default "$@"'
The function should format arguments and put the message into the L_logline variable. -
-F <FORMATFUNC>Equal to -f '"$@"'. Shorthand to use a function. -
-s <SELECTEVAL>If eval "SELECTEVAL" exits with nonzero, do not print the line. Default: '' -
-o <OUTPUTEVAL>Evaluate expression for outputting. Default: L_log_output_to_stderr
The function should output the content of L_logline. -
-LEqual to -F L_log_format_long -
-JEqual to -F L_log_format_json
Arguments: Takes no arguments
L_log_level_inc
¶
increase log level
Argument:
$1
L_log_level_dec
¶
decrease log level
Argument:
$1
L_log_level_to_int_to
¶
Convert log string to number
Arguments:
-
$1str variable name -
$2int|str loglevel likeINFOinfoor30
L_log_is_enabled_for
¶
Check if log of such level is enabled to log.
Argument:
$1
str|int loglevel or log string
L_log_format_default
¶
Default logging formatting
Arguments:
-
$1str log line printf format string -
$@any log line printf arguments
L_log_format_long
¶
Format logline with timestamp information.
Arguments:
-
$1str log line printf format string -
$@any log line printf arguments
L_log_format_json
¶
Output logs in json format.
Shellcheck disable= SC2059
L_log_output_to_stderr
¶
Output L_logline to stderr.
L_log_output_to_logger
¶
Output L_logline with logger.
Argument:
$@
message to output
L_log
¶
main logging entrypoint
Options:
-
-s <int>Increment stacklevel by this much -
-l <int|string>loglevel to print log line as
Argument:
$@
any log arguments
Shellcheck disable= SC2140
Return: 0 if nothing was logged, or the exit status of formatter && outputter functions.
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. -
-hPrint this help and return 0.
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 -
$-1array nameref
L_shuf
¶
Shuffle an array
Argument:
$1
array nameref
L_sort_bash
¶
Quicksort an array in place in pure bash.
Options:
-
-zignored. Always zero sorting -
-nnumeric sort, otherwise lexical -
-rreverse sort -
-c <compare>custom compare function that returns 0 when $1 > $2 and 1 otherwise -
-hPrint this help and return 0.
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-terminateduse zero separated stream with sort -z -
-nnumeric sort
Arguments:
-
$*any options are forwarded to sort command -
$-1last 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:
-
-zUse zero separated stream with sort -z -
-nnumeric sort -
-rreverse sort
Argument:
$1
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_print_caller
¶
Print simple traceback using builtin caller command.
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_names
¶
Return an array of all trap names. Index is the trap name number.
Option:
-v <var>
L_trap_names_v
¶
L_trap_to_number
¶
Convert trap name to number.
The DEBUG ERROR and RETURN traps have a number as reported by $BASH_TRAPSIG inside the handler, but the number can't be used to register the trap with trap command.
Option:
-v <var>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
Argument:
$1
L_trap_get_v
¶
L_trap_push
¶
Add a newline and the command to the trap value.
Arguments:
-
$1str command to execute -
$2str signal to handle
Shellcheck disable= SC2064
See: L_trap_pop
L_trap_pop
¶
Remove a line from the trap value from the end up until the last newline.
Argument:
$1
str signal to handle
Shellcheck disable= SC2064
See: L_trap_push
L_trap
¶
Trap function with reversed order of arguments, to force expansions upon calling.
Arguments:
-
$1Space or comma separated list of signal names or numbers. -
$@Action to execute.
finally
¶
Properly preserve exit status for parent processes. https://www.cons.org/cracauer/sigint.html Re-signaling does not work properly on specific signals. Re-signaling does not work properly in subshells and subshell exits with 0.
Array of commands to execute on EXIT.
_L_finally_arr=()
Array of commands to execute on function returns.
When a function returns at stack depth given by ${#BASH_LINENO[@]} the _L_finally_return[${#BASH_LINENO[@]}] should be executed. _L_finally_return=()
BASHPID that registered traps.
_L_finally_pid=""
Holds signal received inside a critical section.
[0] - signal name [1] - signal number _L_finally_pending=()
Currently handled signal name.
Special values: RETURN EXIT POP NONE POP - when calling from L_finally_pop NONE - used inside critical section. L_SIGNAL=""
Currently handled signal number.
Unset when handling RETURN or POP. 0 for EXIT trap. L_SIGNUM=""
The value of $? as expanded by trap.
L_SIGRET=""
L_finally_handle_return
¶
L_finally RETURN handler.
Arguments:
-
$1The value of $?. -
$2The value of $BASH_COMMAND.
L_finally_handle_exit
¶
L_finally EXIT handler.
L_finally_handle_signal
¶
L_finally signal handler.
Arguments:
-
$1The trap signal name to handle. -
$2The trap signal number to handle.
L_finally_list
¶
List elements registered by L_finally.
L_finally
¶
Register an action to be executed upon termination.
The action will be executed only exactly once, even if the signal is received multiple times.
The signal exit code of the program or subshell is preserved.
The variable $L_SIGNAL is set to the currently handled signal name and available in action.
Warning
The function assumes full ownership of all trap values.
This is needed to properly set traps accross PIDs and subshells and functions and on Bash below 5.2.
Bash below 5.2 does not execute EXIT trap in subshells after receiving a signal,
so L_finally trap handler is registered on all possible signals.
The signal exit status is preserved.
Example
tmpf=$(mktemp)
L_finally rm "$tmpf"
calculate_something() {
local tmpf
tmpf=$(mktemp)
L_finally -r rm "$tmpf"
echo use tmpf >"$tmpf"
# tmpf automatically cleaned up once on RETURN or EXIT or signal, whichever comes first.
}
Options:
-
-rSet trace attribute on the function and add RETURN trap to register the function on.
This does not work correctly with source and instead source RETURN trap will execute parent scope actions. To mitigate this, wrap source in a function, for example use L_source. -
-s <int>Increment the stack offset for the RETURN trap by this number.
The RETURN trap handler will execute the action only if called from the nth position in the stack relative to the current position. Default: 0 -
-lAdd action to be executed last, not first of the stack.
Calling L_finally_pop after registering such action is undefined. -
-RForce reregister all the traps. Unless this option, traps are only registered on the first call of a BASHPID. -
-v <var>Store the action index in the variable.
This index can be used with `L_finally_pop -i` to remove the action. -
-hPrint this help and return 0.
Argument:
$@
Action to execute. When action is missing, then only traps are registered.
The command may not call eval 'return'. It would just return from the handler function.
Shellcheck disable= SC2089 SC2090
See: L_finally_pop
L_finally_pop
¶
Execute and unregister the last action registered with L_finally.
Options:
-
-nDo not execute the action, only remove. -
-i <index>Remove action of index. -
-hPrint this help and return 0.
Return:
1 if nothing was popped, 2 on invalid usage,
otherwise return the exit status of the executed action.
See: L_finally
L_finally_critical_section
¶
Execute a command inside a critical section.
The signals will be raised after the command is finished. Prerequisite: L_finally has registered signal handlers.
Argument:
$@
Command to execute.
with
¶
What we can do with finally? We can do destructors.
L_with_cd
¶
Change to given directory.
Register RETURN trap for parent function that will restore current working directory.
Arguments:
-
$1Directory to cd into. -
$2Optional stack offset to add to RETURN trap.
L_with_tmpfile_to
¶
Create a temporary directory.
Register RETURN trap for parent fuction that will remove the directory.
Arguments:
-
$1Variable to assign the temporary file to. -
$2Optional stack offset to add to RETURN trap.
L_with_tmpdir_to
¶
Create a temporary directory.
Register RETURN trap for parent fuction that will remove the directory.
Arguments:
-
$1Variable to assign the temporary directory location to. -
$2Optional stack offset to add to RETURN trap.
L_with_cd_tmpdir
¶
Create a temporary directory and cd into it.
Register RETURN trap that will remove the temporary directory and restore working directory on return from parent function.
Argument:
$2
Optional stack offset to add to RETURN trap.
L_with_redirect_stdout_to
¶
Temporary redirect stdout to string.
Non-forking command substition for the poor.
Arguments:
-
$1Variable to capture stdout to. -
$2Optional stack offset to add to RETURN trap.
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:
-
-hhelp -
-P <prefix>Get functions with this prefix to test -
-r <regex>filter tests with regex -
-Eexit on error
L_unittest_checkexit
¶
Check if command exits with specified exitcode.
Arguments:
-
$1exit 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:
-
$1var 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:
-
-hPrint this help and return 0. -
-cRun in current execution environment, instead of using a subshell. -
-iInvert exit status. You can also use!orL_notin front of the command. -
-IDo not close stdin <&1 . By default it is closed. -
-fExpect the command to fail. Equal to-i -j -N. -
-NRedirect stdout of the command to >/dev/null. -
-jRedirect stderr to stdout of the command. 2>&1 -
-xRun the command inside set -x -
-XDo not modify set -x -
-v <var>Store the output in variable instead of printing it. -
-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) -
-s <int>Stack up
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:
-
$1variable nameref -
$2value
L_unittest_eq
¶
Test if two strings are equal.
Arguments:
-
$1one string -
$2second string
L_unittest_arreq
¶
Test if array is equal to elements.
Arguments:
-
$1array variable -
$@values
L_unittest_ne
¶
Test two strings are not equal.
Arguments:
-
$1one string -
$2second string
L_unittest_regex
¶
test if a string matches regex
Arguments:
-
$1string -
$2regex
L_unittest_contains
¶
Test if a string contains other string.
Arguments:
-
$1string -
$2needle
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_assign
¶
Initializes a map
Example
local var
L_map_assign var a 1 b 2
Arguments:
-
$1var variable name holding the map -
$@Pairs of keys and values to assign to 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_assign 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:
-
$1var map -
$2str key
L_map_set
¶
Set a key in a map to value
Example
L_map_assign var
L_map_set var a 1
L_map_set var b 2
Arguments:
-
$1var map -
$2str key -
$3str value
L_map_set_noremove
¶
Set a key in a map to value, potentially resulting in duplicate keys.
Arguments:
-
$1var map -
$2str key -
$3str 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_clear var
L_map_set var a 1
L_map_get -v tmp var a
echo "$tmp" # outputs: 1
Option:
-v <var>
Store the output in variable instead of printing it.
Arguments:
-
$1var map -
$2str key -
[$3]str default
L_map_get_v
¶
L_map_has
¶
Example
L_map_clear var
L_map_set var a 1
if L_map_has var a; then
echo "a is set"
fi
Arguments:
-
$1var map -
$2str key
Exit: 0 if map contains key, nonzero otherwise
L_map_setdefault
¶
set value of a map if not set
Arguments:
-
$1var map -
$2str key -
$3str default value
L_map_append
¶
Append value to an existing key in map
Arguments:
-
$1var map -
$2str key -
$3str value to append
L_map_keys
¶
List all keys in the map.
Example
L_map_clear 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>
Store the output in variable instead of printing it.
Argument:
$1
var map
L_map_keys_v
¶
L_map_values
¶
List all values in the map.
Example
L_map_clear 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>
Store the output in variable instead of printing it.
Argument:
$1
var map
L_map_values_v
¶
L_map_items
¶
List items on newline separated key value pairs.
Example
L_map_clear 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>
Store the output in variable instead of printing it.
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_clear 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:
-
$1map variable -
$2prefix -
$@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_clear 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:
-
$1map variable -
$2prefix
asa
¶
Collection of function to work on associative array.
Maybe will renamed to dict. "asa" sounds better than "assarray", less confusing than "asarray" and shorter that 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. Use L_asa_assign
Arguments:
-
$1var Source associative array -
$2var Destination associative array -
[$3]str Filter only keys with this regex
See: L_asa_assign
L_asa_has
¶
check if associative array has key
Arguments:
-
$1associative array nameref -
$2key
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>
Store the output in variable instead of printing it.
Arguments:
-
$1associative array nameref -
$2key -
[$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>
Store the output in variable instead of printing it.
Argument:
$1
associative array nameref
L_asa_len_v
¶
L_asa_keys
¶
get keys of an associative array
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
associative array nameref
L_asa_keys_v
¶
L_asa_keys_sorted
¶
get keys of an associative array in a sorted
Option:
-v <var>
Store the output in variable instead of printing it.
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:
-
$1assoatiative array variable -
$2key to assign to -
$3value to assign
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:
-
$1var Destination associative array -
$2= -
$3var Source associative array
See:
- L_asa_copy
- L_asa_dump
L_asa_cmp
¶
check if one associative array is equal to another
Example
local -A a=([a]=1 [b]=2)
local -A b=([a]=1 [b]=2)
if L_asa_cmp a b; then
echo "equal"
fi
Arguments:
-
$1associative array name -
$2associative array name
Exit: 0 if equal, 1 otherwise
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[@]}" ---- "$@"
L_argparse_validator
¶
Validate arguments inside validator for argparse.
In case of validation error, prints the error message.
Arguments:
-
$1error message -
$2value to validate -
$@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:
-
--ANYAny 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
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
¶
Processes and jobs related functions.
L_bashpid_to
¶
Get bashpid in a way compatible with Bash before 4.0.
Argument:
$1
Variable to store the result to.
L_raise
¶
Send signal to itself.
Argument:
$@
Kill arguments. See kill --help.
L_kill_all_jobs
¶
L_wait_all_jobs
¶
L_get_all_childs
¶
Get all pids of all child processes including grandchildren recursively.
Option:
-v <var>
Argument:
[$1]
Pid of the parent. Default: $BASHPID.
See: https://stackoverflow.com/a/52544126/9072753
L_get_all_childs_v
¶
L_kill_all_childs
¶
Kills all childs of the pid.
Arguments:
-
-sigspecSignal to use. -
[$1]Pid of the process to kill all childs of. Defualt: $BASHPID
L_is_fd_open
¶
Check if file descriptor is open.
Argument:
$1
file descriptor
Shellcheck disable= SC2188
L_get_free_fd_to
¶
Get free file descriptors
Argument:
$@
variables to assign with the file descriptor numbers
L_pipe
¶
Open two connected file descriptors.
This internally 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:
-
<var>variable name to assign result to -
[str]template temporary filename, default: ${TMPDIR:/tmp}/L_pipe_XXXXXXXXXX
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 string with content:
<exitcode> pid<pid> 0fd<stdin> 1fd<stdout> 2fd<stderr>\t<cmd...>.
The outputs variable contains elements:
<exitcode>- Exitcode or empty if not yet finished.<pid>- Pid.<stdin>- If -Ipipe the file descriptor connected to stdin of the program, otherwise empty.<stdout>- If -Opipe the file descriptor connected to stdout of the program, otherwise empty.<stderr>- If -Epipe the file descriptor connected to stderr of the program, otherwise empty.<cmd...>- The %q escaped command that was executed.
You should use getters L_proc_get_* to extract the data from proc variable.
The proc variable is not an array, so it can be used in an array to run many processes.
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 -
-nDryrun mode. Do not execute the generated command. Instead print it to stdout. -
-W <int>Register with L_finally a return trap on stacklevelthat will wait for the popen to finish. Typically -W 0 -
-hPrint this help and return 0.
Arguments:
-
$1variable name to store the result to. -
$@command to execute.
L_proc_get_exitcode
¶
Get exitcode of L_proc.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
L_proc variable
L_proc_get_exitcode_v
¶
L_proc_get_pid
¶
Get PID of L_proc.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
L_proc variable
L_proc_get_pid_v
¶
L_proc_get_stdin
¶
Get file descriptor for stdin of L_proc.
Option:
-v <var>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
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>
Store the output in variable instead of printing it.
Argument:
$1
L_proc variable
L_proc_get_stderr_v
¶
L_proc_get_cmd
¶
Get command of L_proc.
Option:
-v <var>
Store the output in variable instead of printing it.
Argument:
$1
L_proc variable
L_proc_get_cmd_v
¶
L_proc_popen_finally
¶
Handler that can be closed from L_finally or a signal handler.
Closes file descriptors. If L_SIGNAL is a signal, forwards it to the process. Then wait for the process termination.
Example
L_finally proc -W sleep infinity
Example
L_finally proc sleep infinity
L_finally L_proc_popen_finally "$proc"
# or
L_finally proc sleep infinity
L_finally L_eval 'L_proc_popen_finally "${!1}"' proc
Argument:
$1
L_proc value. This is because the variable may go out of scope.
This is bad. when closing a file descriptor, we "remember" that the file descriptor was closed in the variable. This is less then ideal, but I do not know at this time how to fix it better. Potentially, this can cause unrelated file descriptors to get closed. This might change in the future.
L_proc_printf
¶
Write printf formatted string to coproc.
Arguments:
-
$1L_proc variable -
$@any printf arguments
L_proc_read
¶
Exec read bultin with -u file descriptor of stdout of coproc.
Arguments:
-
$1L_proc variable -
$@any builtin read options
L_proc_read_stderr
¶
Exec read bultin with -u file descriptor of stderr of coproc.
Arguments:
-
$1L_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_wait
¶
Wait for pids to be finished with a timeout and capture exit codes.
Tries to use waitpid or tail --pid or a busy loop for best performance.
The waiting is uninterruptible by signals.
Note: builtin kill with multiple pids has different exit code depending on posix mode.
Options:
-
-t <timeout>Wait for this long. Timeout 0 results in just collecting all pids. -
-v <var>Exit code of PIDs will be assigned to . The elements of -v and -p arrays are pairs. -
-p <var>PIDs that exited will be assigned to array variable . -
-l <var>Left running PIDs will be assigned to array variable . -
-P <polltime>The time to poll processes when not possible to use waitpid or tail. Default: 0.1 -
-nReturn 0 when at least one of the pids is finished. -
-bBash only. Do not use waitpid or tail. -
-hPrint this help and exit.
Argument:
$@
pids to wait on
Return:
0 on success
2 usage error
124 timeout
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>Store the output in variable instead of printing it. -
-cClose L_proc file descriptors before waiting. -
-hPrint this help and return 0.
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.
Note
The minimum read -t argument in Bash3.2 is 1 second. It is not possible
to set it lower or to a fraction. This does not work great for Bash3.2 for short timeout, as one read takes at least 1 second to execute.
Example
exec 10< <(for ((i=0;i<5;++i)); do echo $i; sleep 1; done)
exec 11< <(for ((i=0;i<5;++i)); do echo $i; sleep 2; done)
Options:
-
-t <timeout>Timeout in seconds. -
-p <timeout>Poll timeout. The read -t argument value. Default: 0.05 or 1 in Bash3.2 -
-hPrint this help and return 0. -
-n <var>When the first fd errors or becomes EOF and assign it's number to and return 0. -
-C <callback>Each time any chunk of data is read,
evaluate the expression "<callback> <fd> <variable> <line>". -
-d <delim>Read -d argument. Default: '' -
-1Run the loop until all file descriptors timeout.
Arguments:
-
$1File descriptor to read from. -
$2Variable to assign the output of $1. -
$@Continued pairs of file descriptor and variable names.
Return:
0 on success
124 on timeout
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. -
-kKill L_proc after communication. -
-v <var>Store the output in variable instead of printing it. -
-hPrint this help and return 0.
Argument:
$1
L_proc variable
Exit: 0 on success. 2 on invalid options. 124 on timeout.
L_proc_send_signal
¶
Send signal to L_proc.
Arguments:
-
$1L_proc variable -
$2signal to send
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.