Skip to content

Library providing useful functions for Bash

License

Notifications You must be signed in to change notification settings

georglauterbach/libbash

Repository files navigation

libbash

test bats linting

About

libbash provides pure Bash functions like a library. libbash focuses on very high code quality and safe functions without common Bash side effects. Bash is difficult because it is extremely liberal. This project provides robust functions, checked by ShellCheck and by BATS.

Caution
These functions are not POSIX compatible, i.e., they do not work with sh, only with bash. This project is written in and supports Bash v5.0.

Usage

Locally

During this usage demonstration, consider the following directory and file structure:

your_repository/
├── some_script.sh
├── some_dir/
│   └── some_other_script.sh
└── libbash/
    ├── ...
    ├── load
    └── ...

To source load - the script that handles the complete initialization of libbash - from some_script.sh, you can use the following command:

source libbash/load 'errors' 'log'
SCRIPT='some script'

This example assumes the script some_script.sh is executed (or sourced) from the directory it lives in (i.e., your_repository). To source libbash independently of the invocation location, for example in some_dir/some_other_script.sh, you may use this more elaborate call to source:

source "$(realpath -eL "$(dirname "${BASH_SOURCE[0]}")/../libbash/load")" 'errors' 'log'
SCRIPT='some other script'

Remotely

You may also use libbash without cloning the repository. To do so, run:

source <(curl -qsSfL https://github.com/raw/georglauterbach/libbash/main/load) --online <VERSION> 'log'

You need to specify a version to acquire modules from a specific release. Versions follow the Semantic Versioning pattern and can be found on the Releases page on GitHub. You may also use main as a version to indicate you want to use the very latest updates of libbash.

Environment Variables

Internal Variables

When libbash is loaded, it uses variables that start with __LIBBASH__ to manage internal state. These variables are marked with readonly, hence they are not modifiable. Users of libbash are not supposed to use these variables. Due to the way Bash handles scoping, having these variables in the global scope is inevitable.

Exit in Interactive Mode

When using libbash on an interactive prompt, you can use export LIBBASH_EXIT_IN_INTERACTIVE_MODE=1 to specify that you want the prompt to quit when

  1. the error module is loaded, and

  2. an unhandled error is thrown.

The default is 0, i.e., your interactive prompt will not close by default.

Modules

When you load libbash, you don’t have to use all the code that libbash actually contains. libbash provides different modules. When you source the load script, you can provide the modules you would like to use as arguments.

To load a module, just specify its name after the source command, as shown in the examples above in the usage section. All modules are located in the modules directory, and their name is just the file name without .sh at the end. When you open the file, you will see all the functions the module provides. These functions have Rust-like documentation comments above their definitions to give you a concise overview of what the function does.

cri

This module provides the setup_container_runtime function to detect the container runtime. It will set the CRI variable to docker or podman or return with exit status 1 if no container runtime could be identified.

errors

This module provides a very strict set of error primitives (e.g., set -e, set -E) to show and handle errors. The use of this module is recommended, but the set of rules imposed by this module is very strict. One might want to circumvent this by manually reverting some settings, for example with set +e after loading the module.

log

This module provides the log function. log is invoked by first specifying the log level:

  1. error

  2. warn

  3. info

  4. debug

  5. trace

This is followed by the actual message (i.e., log 'info' 'Some info message'). You can supply many arguments to log, but the first argument must be the log level. This function is guaranteed to not fail.

The log level itself can be changed anytime by setting LOG_LEVEL to one of the levels described above. Naturally, messages below the log level are not shown. The default LOG_LEVEL is info. If the environment variable LOG_LEVEL does not contain a valid log level, LOG_LEVEL is reset to info upon calling log.

utils

This module provides various miscellaneous functions, like escape to escape characters or exit_failure to exit with an error.

Licensing

This project is licensed under the MIT license, see LICENSE.