DevOps Scripting PatternsLesson 6.5
Building a self-contained Bash CLI tool
CLI tool structure, subcommand dispatch, help generation, version flag, --completion support, color detection, install and uninstall targets, Makefile integration, distributing Bash scripts
Structure of a Multi-Subcommand CLI
Real CLI tools use a dispatcher pattern: a main script that routes to subcommand functions or files based on the first argument.
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.0.0"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
usage() {
cat << EOF
mytool v${VERSION}
Usage: mytool [options]
Commands:
deploy Deploy an application
rollback Roll back to previous version
status Show deployment status
help Show this message
Options:
--version Show version
--help Show help
EOF
}
main() {
local cmd="${1:-help}"
shift || true
case "$cmd" in
deploy) source "${SCRIPT_DIR}/commands/deploy.sh"; cmd_deploy "$@" ;;
rollback) source "${SCRIPT_DIR}/commands/rollback.sh"; cmd_rollback "$@" ;;
status) source "${SCRIPT_DIR}/commands/status.sh"; cmd_status "$@" ;;
--version) echo "mytool $VERSION" ;;
help|--help|-h) usage ;;
*) echo "Unknown command: $cmd" >&2; usage; exit 1 ;;
esac
}
main "$@" Install Target
# In Makefile:
install:
install -m 755 mytool /usr/local/bin/mytool
install -d /usr/local/lib/mytool
cp -r commands lib /usr/local/lib/mytool/
uninstall:
rm -f /usr/local/bin/mytool
rm -rf /usr/local/lib/mytoolFor distribution, bundle everything into a single self-extracting script using a heredoc that writes the library files to a temp directory at runtime — useful when users can't run make install.
