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:
- 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_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.