| name | bash-cli-framework |
| version | 1.0.0 |
| description | Universal bash CLI patterns for colors, logging, headers, and error handling |
| author | workspace-hub |
| category | bash |
| tags | ["bash","cli","colors","logging","framework","scripting"] |
| platforms | ["linux","macos"] |
Bash CLI Framework
A comprehensive framework for building consistent, professional bash CLI tools with standardized colors, logging, headers, and error handling patterns extracted from workspace-hub scripts.
When to Use This Skill
✅ Use when:
- Building new bash CLI tools or scripts
- Adding consistent output formatting to existing scripts
- Need standardized error handling and logging
- Creating user-friendly interactive scripts
- Building tools that will be used across multiple repositories
❌ Avoid when:
- Simple one-liner scripts
- Scripts that don't produce user-facing output
- When Python/Node CLI frameworks are more appropriate
Core Capabilities
1. Color Definitions
Standard ANSI color codes for consistent terminal output:
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
WHITE='\033[1;37m'
NC='\033[0m'
BOLD='\033[1m'
BOLD_RED='\033[1;31m'
BOLD_GREEN='\033[1;32m'
BOLD_YELLOW='\033[1;33m'
BOLD_BLUE='\033[1;34m'
echo -e "${GREEN}✓ Success${NC}"
echo -e "${RED}✗ Error${NC}"
echo -e "${YELLOW}⚠ Warning${NC}"
echo -e "${CYAN}ℹ Info${NC}"
2. Script Header Template
Every script should start with proper identification:
#!/bin/bash
set -e
SCRIPT_NAME="$(basename "$0")"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VERSION="1.0.0"
3. Logging Functions
Standardized logging with timestamps and levels:
#!/bin/bash
LOG_FILE="${LOG_FILE:-/tmp/${SCRIPT_NAME}.log}"
LOG_LEVEL="${LOG_LEVEL:-INFO}"
declare -A LOG_LEVELS=(
["DEBUG"]=0
["INFO"]=1
["WARNING"]=2
["ERROR"]=3
["CRITICAL"]=4
)
log() {
local level="$1"
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
if [[ ${LOG_LEVELS[$level]} -ge ${LOG_LEVELS[$LOG_LEVEL]} ]]; then
case "$level" in
DEBUG) echo -e "${CYAN}[${timestamp}] DEBUG${NC} - $message" ;;
INFO) echo -e "${GREEN}[${timestamp}] INFO${NC} - $message" ;;
WARNING) echo -e "[] WARNING - " ;;
ERROR) -e >&2 ;;
CRITICAL) -e >&2 ;;
>>
}
() { ; }
() { ; }
() { ; }
() { ; }
() { ; }
4. Display Headers
Professional header/banner display:
#!/bin/bash
print_header() {
local title="$1"
local width="${2:-60}"
local char="${3:-═}"
local line=$(printf "%${width}s" | tr ' ' "$char")
echo ""
echo -e "${CYAN}${line}${NC}"
echo -e "${CYAN} ${title}${NC}"
echo -e "${CYAN}${line}${NC}"
echo ""
}
print_section() {
local title="$1"
echo ""
echo -e "${BOLD}${title}${NC}"
echo -e "${CYAN}$(printf '%.0s─' {1..40})"
}
() {
status=
message=
success) -e ;;
error) -e ;;
warning) -e ;;
info) -e ;;
pending) -e ;;
skip) -e ;;
}
5. Error Handling
Robust error handling with cleanup:
#!/bin/bash
cleanup() {
local exit_code=$?
[[ -n "$TEMP_DIR" && -d "$TEMP_DIR" ]] && rm -rf "$TEMP_DIR"
if [[ $exit_code -eq 0 ]]; then
log_info "Script completed successfully"
else
log_error "Script exited with code $exit_code"
fi
exit $exit_code
}
trap cleanup EXIT INT TERM
die() {
local message="$1"
local exit_code="${2:-1}"
log_critical "$message"
exit "$exit_code"
}
assert() {
local condition="$1"
local message="${2:-Assertion failed}"
! ;
die
}
6. Argument Parsing
Standard argument parsing pattern:
#!/bin/bash
VERBOSE=false
DRY_RUN=false
CONFIG_FILE=""
show_usage() {
cat << EOF
Usage: $SCRIPT_NAME [OPTIONS] <arguments>
Options:
-h, --help Show this help message
-v, --verbose Enable verbose output
-n, --dry-run Show what would be done without doing it
-c, --config FILE Use specified configuration file
--version Show version information
Examples:
$SCRIPT_NAME --verbose process
$SCRIPT_NAME -c config.yaml --dry-run
EOF
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_usage
exit 0
;;
-v|--verbose)
VERBOSE=true
LOG_LEVEL="DEBUG"
shift
;;
-n|--dry-run)
DRY_RUN=true
shift
;;
-c|--config)
CONFIG_FILE="$2"
shift 2
;;
--version)
echo "$SCRIPT_NAME version $VERSION"
exit 0
;;
--)
shift
break
;;
-*)
die "Unknown option: $1"
;;
*)
;;
ARGS=()
}
Complete Example
A complete script using all framework components:
#!/bin/bash
set -e
SCRIPT_NAME="$(basename "$0")"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VERSION="1.0.0"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
VERBOSE=false
DRY_RUN=false
LOG_LEVEL="INFO"
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
log_warning() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR] $*" >&2; }
() { log_error ; ; }
() {
-e
-e
-e
}
() {
<<
}
() {
exit_code=$?
[[ == ]] && log_info
}
cleanup EXIT INT TERM
() {
[[ -gt 0 ]];
-h|--) show_usage; 0 ;;
-v|--verbose) VERBOSE=; ;;
-n|--dry-run) DRY_RUN=; ;;
--version) ; 0 ;;
-*) die ;;
*) ;;
=
[[ -z ]] && { show_usage; die ; }
print_header
run)
log_info
[[ == ]] && log_warning
;;
status)
log_info
;;
clean)
log_info
;;
*)
die
;;
log_info
}
main
Best Practices
1. Always Use set -e
Exit immediately if a command exits with non-zero status:
set -e
set -euo pipefail
2. Quote Variables
Always quote variables to prevent word splitting:
echo "$variable"
"$command" "$arg1" "$arg2"
echo $variable
$command $arg1 $arg2
3. Use Meaningful Exit Codes
EXIT_SUCCESS=0
EXIT_ERROR=1
EXIT_USAGE=2
EXIT_CONFIG=3
4. Provide Feedback
Always tell the user what's happening:
log_info "Starting process..."
log_info "Process complete (processed $count items)"
5. Support Dry Run
Let users preview changes:
if [[ $DRY_RUN == true ]]; then
log_info "[DRY RUN] Would execute: $command"
else
eval "$command"
fi
Integration with workspace-hub
This framework is used across all workspace-hub scripts:
scripts/monitoring/suggest_model.sh
scripts/monitoring/check_claude_usage.sh
scripts/workspace
scripts/repository_sync
Resources
Version History
- 1.0.0 (2026-01-14): Initial release - extracted from workspace-hub scripts