BAMF
The BASH Application Management Framework. You source one file, bamf.inc,
and your script gets consistent logging, named exit codes, temporary files
that are always cleaned up, dependency checks, signal handling, and a set of
everyday helpers for strings, files, and configuration.
It grew over many years of production scripting: deployment hooks, CI pipelines, server setup, and the glue between them. We publish it so other people can write reliable scripts faster, and to show, in working code, the bash practices that make scripts dependable.
A quick look
The core of the hello.sh example:
#!/bin/bash
# purpose: A first BAMF script: logging, a temporary file, and a clean exit
# version: 1.0.0
SELF_IDENTITY="hello"
source "$(dirname "${BASH_SOURCE[0]}")/../bamf.inc" || exit 3
start_logic
line_break
log_highlight "Execution"
log "Hello, ${NAME}"
# Removed automatically when the script exits, however it exits
generate_temp_file FILE_GREETING "greeting"
printf 'Hello, %s\nfrom %s\n' "${NAME}" "$(return_hostname)" > "${FILE_GREETING}"
log_add_from_file "${FILE_GREETING}" "greeting"
log_success "Said hello"
exit_logic 0
Every log line names the script that wrote it, so the output of several scripts stays readable in a CI job or a deployment log. On a terminal the lines are in color; in a log file, CI job, or cron mail, each line gets a timestamp instead:
2026-10-22 14:16:38 [hello] SUCCESS: Said hello
2026-10-22 14:16:38 [hello] SCRIPT_FINISHED: (Duration::0m 00.021s / Exit_Code::0 [success])
What you get
- Logging that looks the same in every script: notices, warnings, errors, highlighted sections, and file contents with line numbers.
- Named exit codes.
exit_logic "${E_OBJECT_NOT_FOUND}"exits with 8, and the log saysE_OBJECT_NOT_FOUND / Object not found. Define your own withdefine_exit_code. - A guaranteed ending. Temporary files are removed and the exit code is
logged whether the script finishes, fails under
set -e, or is stopped with Ctrl+C. Register your own cleanup withadd_exit_function. - Dependency checks before any work starts, so a missing command stops the script cleanly instead of halfway through.
- Secrets kept out of logs, and passed to commands through a private file instead of the command line, where any user could see them.
- Configuration helpers that read properties, dotenv, key/value, and simple YAML files.
- Optional helper files for AWS, curl, Docker, Git, npm, package management, tar, and Terraform, loaded only by the scripts that need them.
Getting started
There is nothing to install. Copy bamf.inc, and any helper files you want,
next to your scripts. It needs bash 4.2 or newer and GNU coreutils; the tests
run on bash 4.2 (CentOS 7) and bash 5.2 (Debian 12, Amazon Linux 2023).
The repository’s README walks through the shape every BAMF script follows, the configuration settings, how exit codes are numbered, and every function.
Learn from it
BAMF is meant to be read as well as used. Its README explains the techniques
in it that are worth knowing for any bash script, and where to find them in
the code: returning values with printf -v instead of eval, cleaning up
in an EXIT trap, guarding every rm -rf built from variables, keeping
secrets out of the process list, and working under set -euo pipefail on
every bash back to 4.2.
The examples each teach one idea and are run by the test suite, so they keep working. They range from a first script to reading and checking a configuration file, downloading and verifying a file, backing up to S3 with a KMS key, and a complete set of AWS CodeDeploy hooks for a containerized application.
Links
BAMF is licensed under the Apache License 2.0. The BAMF name and logo are not licensed.