A comprehensive, modular bash library for developers who want powerful, readable shell scripting
Bash-lib transforms shell scripting from a cryptic art into a developer-friendly experience. With structured logging, HTTP clients, file management, user management, and more - all wrapped in clean, readable APIs.
# Install latest version
curl -sSL https://raw.githubusercontent.com/openbiocure/bash-lib/main/scripts/install.sh | bash
# Install specific version
curl -sSL https://raw.githubusercontent.com/openbiocure/bash-lib/main/scripts/install.sh | bash -s v1.0.0
# Install specific build
curl -sSL https://raw.githubusercontent.com/openbiocure/bash-lib/main/scripts/install.sh | bash -s 20241201-abc123
git clone https://github.com/openbiocure/bash-lib
cd bash-lib
make install-deps
make install
console
- Structured logging with colors and verbosity controlprocess
- Process management and monitoring
http
- Full-featured HTTP client with retries, timeouts, and status checking
directory
- Comprehensive file/directory operations with search and filteringpermissions
- User-friendly permission management with readable constantscompressions
- Archive creation and extraction (tar, zip, gzip)
users
- Complete user and group management system
math
- Mathematical operations and calculationsstring
- String manipulation and validationdate
- Date and time utilities
# Source the library (BASH__PATH is auto-detected)
source lib/core/init.sh
# Import modules
import console
import http
import directory
import permissions
console.log "Application started"
console.info "Processing user input"
console.debug "Variable value: $user_input"
console.warn "Deprecated function called"
console.error "Failed to connect to database"
console.success "User created successfully"
# Simple GET request
http.get "https://api.example.com/data"
# POST with data
http.post "https://api.example.com/submit" --data='{"name":"John","age":30}'
# Download file with retries
http.download "https://example.com/file.zip" "/tmp/file.zip"
# Check if service is up
if http.is_200 "https://api.example.com/health"; then
console.success "Service is healthy"
fi
# Create directory with parents
directory.create "/path/to/new/dir" --parents
# Search for files
directory.search "/home/user" "*.log" --depth=3 --max=10
# Get directory size
size=$(directory.size "/var/log" --human-readable)
# List with options
directory.list "/tmp" --all --long --sort=date
# Set permissions using readable constants
permissions.set "file.txt" $PERM_SHARED_READ
permissions.set "script.sh" $PERM_SHARED_EXEC
# Make executable
permissions.make_executable "script.sh"
# Set ownership
permissions.own "file.txt" "user:group"
# Secure a file (private to owner)
permissions.secure "secret.txt"
# Create user with custom options
users.create "john" --home="/home/john" --shell=$USER_SHELL_BASH
# Create group and add user
users.create_group "developers"
users.add_to_group "john" "developers"
# List users
users.list --regular-only
# Get user info
users.info "john"
# Check if string is empty
if [[ $(string.isEmpty "$input") == "true" ]]; then
console.error "Input is required"
fi
# Convert case
uppercase=$(string.upper "hello world")
lowercase=$(string.lower "HELLO WORLD")
# String manipulation
trimmed=$(string.trim " hello ")
length=$(string.length "hello")
# Check patterns
if [[ $(string.contains "hello world" "world") == "true" ]]; then
console.info "Found 'world' in string"
fi
# Create tar archive
compression.tar "backup.tar" "file1.txt" "dir1/"
# Extract tar archive
compression.untar "backup.tar" "/tmp/extracted"
# Compress with gzip
compression.gzip "large_file.txt"
# Create zip archive
compression.zip "archive.zip" "file1.txt" "file2.txt"
make help # Show all available targets
make install-deps # Install development dependencies
make test # Run unit tests
make man # Generate Manual.md from module help
make install # Install bash-lib locally
# Run all tests
make test
# Run specific module tests
shellspec spec/directory_spec.sh --shell /bin/bash
# Run with verbose output
shellspec --shell /bin/bash -e BASH__VERBOSE=debug
# Generate Manual.md from all module help functions
make man
# View the generated manual
cat Manual.md
Variable | Description | Default |
---|---|---|
BASH__PATH |
Library root location (auto-detected by init.sh if unset) |
/opt/bash-lib |
BASH__VERBOSE |
Log verbosity level | info |
Note: You usually do not need to set
BASH__PATH
manually. The library will auto-detect its root directory when you sourcelib/core/init.sh
. Only set it if you want to override the default detection.
trace
- Show all log messagesdebug
- Show debug and aboveinfo
- Show info and abovewarn
- Show warnings and aboveerror
- Show errors and above
# Set verbosity level
console.set_verbosity debug
# Check current level
current_level=$(console.get_verbosity)
bash-lib/
├── core/ # Core functionality
│ ├── init.sh # Library initialization
│ ├── engine.mod.sh # Module engine
│ └── trapper.mod.sh # Signal handling
├── modules/ # Feature modules
│ ├── system/ # System utilities
│ │ ├── console.mod.sh # Logging
│ │ └── process.mod.sh # Process management
│ ├── http/ # HTTP client
│ ├── directory/ # File operations
│ ├── permissions/ # Permission management
│ ├── users/ # User management
│ ├── compressions/ # Archive operations
│ ├── math/ # Mathematical operations
│ ├── utils/ # Utility functions
│ └── date/ # Date/time utilities
├── config/ # Configuration files
├── spec/ # Unit tests
├── assets/ # Static assets
└── Manual.md # Auto-generated documentation
# Enable bash debugging
set -x
# Your code here
import console
console.debug "Debug message"
set +x
# List all bash-lib environment variables
env | grep BASH__
# Check module availability
ls modules/*/
Issue: bash-lib previously failed with "unbound variable" errors when using strict error handling (set -u
or set -euo pipefail
).
Error Message:
/opt/bash-lib/lib/init.sh: line 87: !signal: unbound variable
Root Cause: Unguarded variable expansions in module import system and array access patterns throughout the codebase.
Status: ✅ RESOLVED - All unguarded variable expansions have been fixed with proper default values.
Fix Applied:
- Added default values for all array access:
${array[index]:-}
- Fixed indirect variable expansion:
${!signal:-}
- Updated all modules to be compatible with
set -u
- Enhanced CI to test with strict error handling
Related: GitHub Issue #18
Note: bash-lib now fully supports strict error handling. You can safely use
set -u
in your scripts.
All contributors must follow our Code of Conduct.
Shell Scripting Policy:
This project enforces strict shell scripting best practices, including the mandatory use of
set -u
(nounset) and proper guarding of all variable and array expansions. Please read the Code of Conduct for details.
- Fork the repository
- Create a feature branch
- Add your module or improvements
- Write tests for your changes
- Submit a pull request
- Follow the existing module structure
- Add comprehensive help functions
- Include unit tests
- Use descriptive function names
- Add proper error handling
- Document all functions with examples
# Find all TODO and FIXME comments
egrep -Rin "TODO|FIXME" -R *
- Manual.md - Auto-generated from module help functions
- CHANGELOG.md - Complete change history
- Module Help - Each module has built-in help:
module.help
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: GitHub Issues
- Documentation: Run
make man
to generate the latest manual - Module Help: Run
module.help
for any module's documentation
Transform your bash scripts from cryptic commands into readable, maintainable code with bash-lib! 🚀