Skip to content
/ smack Public

🧨 Smack your bash up - Create scripts Safer, Better, Faster, Stronger

License

trentas/smack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

61 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

smack 🧨

Write safer, cleaner bash scripts in half the time

A battle-tested Bash utility library that eliminates boilerplate, prevents common pitfalls, and makes your scripts production-ready from day one.

Shellcheck License: MIT Bash Security Hardened


Why smack?

The Problem 😫

Writing production-ready bash scripts is harder than it should be:

# Typical bash script problems:
❌ Passwords visible in process lists
❌ SQL injection vulnerabilities
❌ No proper error handling
❌ Inconsistent logging
❌ Copy-paste boilerplate everywhere
❌ Race conditions with concurrent runs
❌ No input validation

The Solution ✨

smack gives you battle-tested tools so you can focus on what your script does, not how:

#!/usr/bin/env smack

# That's it! Now you have:
βœ… Secure database operations (no passwords in process lists)
βœ… SQL injection prevention (automatic input sanitization)
βœ… Professional logging (with colors, emojis, syslog)
βœ… Process lifecycle management (PID files, cleanup handlers)
βœ… Input validation (YAML, email, database inputs)
βœ… Zero dependencies (pure bash, works everywhere)

🎯 Quick Start

Installation

git clone https://github.com/trentas/smack.git
cd smack
make install

Your First Script

Create hello.sksh:

#!/usr/bin/env smack

s.check.os                           # Verify supported OS
s.print.log info "Hello, smack! πŸ‘‹"  # Beautiful logging
s.print.log notice "Processing..."   # With colors and emojis
s.process.run ls -la                 # Run commands with logging

Run it:

chmod +x hello.sksh
./hello.sksh

Output:

INFO   hello.sksh:main:4 Hello, smack! πŸ‘‹
NOTICE hello.sksh:main:5 Processing...
DEBUG  hello.sksh:main:6 running: ls -la

πŸš€ Features

πŸ”’ Security First

  • SQL Injection Prevention: Automatic input validation for database operations
  • Secure Password Handling: Uses environment variables, never exposes passwords in process lists
  • YAML Injection Prevention: Validates YAML files before parsing to prevent code injection
  • Command Injection Protection: Email subjects and user inputs are sanitized
  • 100% Shellcheck Compliant: Zero warnings, zero errors, professional code quality

πŸ“Š Professional Logging

s.print.log debug "Debugging information"      # πŸ” Purple
s.print.log info "Something happened"          # πŸ’Ž Blue  
s.print.log notice "Pay attention to this"     # πŸ”Ά Green
s.print.log warn "Warning message"             # ⚠️  Yellow
s.print.log error "Something went wrong"       # ❌ Red
  • Automatic syslog integration
  • Colorful terminal output
  • Function call tracking with line numbers
  • Configurable log levels

πŸ—„οΈ Database Management

# Secure MySQL operations (MySQL 5.7, 8.0+)
s.db.create.database mysql localhost "$ROOT_PASS" "myapp_db"
s.db.create.user mysql localhost "$ROOT_PASS" "app_user" "$USER_PASS"
s.db.set.grants mysql localhost "$ROOT_PASS" "myapp_db" "app_user" "ALL PRIVILEGES"

# All inputs are validated to prevent SQL injection
# Passwords never appear in process lists

πŸ”„ Process Management

#!/usr/bin/env smack

s.process.single  # Ensure only one instance runs at a time

# Your script logic here
s.process.run "backup-database.sh"
s.process.run "compress-logs.sh"

# Cleanup happens automatically on exit (even on errors!)

πŸ“§ Integrations

# Send Slack notifications
s.print.slack info "Deployment started! πŸš€"
s.print.slack error "Build failed! ❌"

# Send emails  
echo "Report attached" | s.email.send "Daily Report"

# Load configuration from YAML
s.load.yaml config.yaml  # Variables exported with s_config_ prefix

βš™οΈ Configuration Management

# config.yaml
database:
  host: localhost
  name: production
slack:
  url: https://hooks.slack.com/...
  channel: "#alerts"
#!/usr/bin/env smack

s.load.yaml config.yaml

# Now you have:
# $s_config_database_host = "localhost"
# $s_config_database_name = "production"
# $s_config_slack_url = "https://..."
# $s_config_slack_channel = "#alerts"

πŸ“š Real-World Examples

Database Backup Script

#!/usr/bin/env smack

s.process.single                    # Only one backup at a time
s.check.root                        # Must run as root
s.load.yaml /etc/backup-config.yaml

BACKUP_FILE="/backups/db-$(date +%Y%m%d).sql.gz"

s.print.log info "Starting database backup..."
s.print.slack info "πŸ“¦ Database backup started"

if s.process.run mysqldump "$DB_NAME" | gzip > "$BACKUP_FILE"; then
    SIZE=$(s.print.human_readable $(stat -f%z "$BACKUP_FILE"))
    s.print.log info "Backup complete: $SIZE"
    s.print.slack info "βœ… Backup complete: $SIZE"
else
    s.print.log error "Backup failed!"
    s.print.slack error "❌ Backup failed!"
    exit 1
fi

Application Deployment Script

#!/usr/bin/env smack

s.process.single
s.check.requirements? git docker docker-compose

s.print.log info "Deploying application..."
s.print.slack info "πŸš€ Deployment started"

# Pull latest code
s.process.run git pull origin main

# Generate secure database password
DB_PASS=$(s.print.password 32)

# Set up database
s.db.create.database mysql localhost "$ROOT_PASS" "app_prod"
s.db.create.user mysql localhost "$ROOT_PASS" "app_user" "$DB_PASS"
s.db.set.grants mysql localhost "$ROOT_PASS" "app_prod" "app_user" "ALL PRIVILEGES"

# Deploy
s.process.run docker-compose up -d

s.print.log info "Deployment complete! πŸŽ‰"
s.print.slack info "βœ… Deployment successful!"

System Health Check

#!/usr/bin/env smack

s.check.requirements? df free uptime

# Check disk space
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 80 ]; then
    s.print.log warn "Disk usage at ${DISK_USAGE}%"
    s.print.slack warn "⚠️ Disk usage high: ${DISK_USAGE}%"
fi

# Check memory
MEM_AVAILABLE=$(free -m | awk 'NR==2 {print $7}')
if [ "$MEM_AVAILABLE" -lt 500 ]; then
    s.print.log warn "Low memory: ${MEM_AVAILABLE}MB available"
    s.print.slack warn "⚠️ Low memory: ${MEM_AVAILABLE}MB"
fi

# System uptime
UPTIME=$(uptime -p)
s.print.log info "System status OK - $UPTIME"

🧰 Complete Function Reference

System Checks

Function Description
s.check.os Validates OS compatibility (Linux/macOS, Bash 5+)
s.check.root Ensures script runs as root
s.check.requirements? cmd1 cmd2 Verifies required commands exist
s.check.variable? $VAR Checks if variable is set
s.check.directory? /path Verifies directory exists
s.check.file? /path/file Checks if file exists and is not empty
s.check.writable? /path Verifies path is writable

Logging & Output

Function Description
s.print.log LEVEL "message" Logs to stdout and syslog (debug/info/notice/warn/error)
s.print.slack LEVEL "message" Sends message to Slack with color coding
s.print.human_readable NUM Converts bytes to human format (1.2 GB)
s.print.password [LENGTH] Generates secure random password (default: 16 chars)

Database Operations (MySQL)

Function Description
s.db.sanitize? VALUE TYPE Validates input (username/database/hostname/grants)
s.db.create.database Creates database with validation
s.db.create.user Creates user with secure password handling
s.db.set.grants Sets user privileges with validation
s.db.set.password Updates password (MySQL 8.0+ compatible)
s.db.delete.grants Revokes privileges
s.db.delete.user Removes user
s.db.delete.database Drops database

Process Management

Function Description
s.process.run CMD ARGS Executes command with logging
s.process.single Ensures only one instance runs (PID file)
s.process.cleanup Cleanup handler (called automatically on exit)

Configuration

Function Description
s.load.yaml FILE Parses YAML to environment variables (s_config_*)
s.set.variables Initializes default variables
s.set.colors Sets up terminal colors
s.set.emojis Defines emoji shortcuts
s.set.verbose Enables bash debug mode

Communications

Function Description
s.email.send "SUBJECT" Sends email from stdin with sanitization
s.print.slack LEVEL "msg" Slack notification with validation

πŸ† Why Choose smack?

vs Raw Bash Scripts

Feature Raw Bash smack
Logging Manual echo statements Professional logging with levels, colors, syslog
Security Manual validation everywhere Automatic input validation & sanitization
Error Handling Custom trap handlers Built-in cleanup & error handling
Process Control Complex PID file logic Simple s.process.single
Code Reuse Copy-paste boilerplate Import once, use everywhere
Learning Curve Steep (bash gotchas) Gentle (sensible defaults)
Maintenance High (scattered code) Low (centralized functions)

vs Other Bash Frameworks

  • bashful: smack is lighter and more focused on practical tasks
  • bash-oo-framework: smack doesn't try to make bash OOP, stays idiomatic
  • bash-it: smack is for scripting, not interactive shell customization
  • bats: smack complements bats (use both!)

Key Differentiators

βœ… Security Hardened: Comprehensive SQL injection prevention, password security
βœ… Production Ready: 100% shellcheck compliant, zero warnings
βœ… Zero Dependencies: Pure bash, works on any Unix-like system
βœ… Battle Tested: Used in production environments
βœ… Well Documented: Clear examples for every function
βœ… Active Development: Regular updates and improvements


πŸ“Š Code Quality

smack maintains the highest standards:

  • βœ… 100% Shellcheck Compliant - Zero errors, zero warnings
  • βœ… Security Audited - See SECURITY_FIXES.md
  • βœ… Input Validation - All user inputs are validated and sanitized
  • βœ… Proper Quoting - Prevents word splitting and globbing issues
  • βœ… Error Handling - Comprehensive error checking throughout
  • βœ… Documented - Every function has clear documentation

See SHELLCHECK_FIXES.md for details on the 200+ improvements made.


πŸ› οΈ Advanced Usage

Custom Configuration

#!/usr/bin/env smack

# Override defaults
s_config_debug="no"                    # Disable debug output
s_config_syslog_facility="local5"     # Change syslog facility

# Your script logic

Extending smack

# Create your own functions
function my.custom.function() {
    s.print.log info "My custom logic"
    # Your code here
}

# Use smack functions inside
my.custom.function

Integration with Existing Scripts

#!/bin/bash

# Source smack manually in existing scripts
source /usr/local/bin/smack

s.print.log info "Now using smack features!"

πŸ” Security

smack takes security seriously. All recent security enhancements:

  • βœ… Password Security: Uses MYSQL_PWD environment variable (not visible in ps)
  • βœ… SQL Injection Prevention: Input validation for all database operations
  • βœ… YAML Injection Prevention: Safe parsing with validation
  • βœ… Command Injection Prevention: Email and input sanitization
  • βœ… MySQL 8.0+ Compatible: Uses modern ALTER USER syntax
  • βœ… Webhook Validation: Slack URLs are validated before use
  • βœ… Timeout Protection: Network operations have timeouts

See full security audit: SECURITY_FIXES.md


🀝 Contributing

Contributions are welcome! Please:

  1. Run shellcheck: All code must pass shellcheck with zero warnings
  2. Validate inputs: Always validate user inputs
  3. Use proper quoting: Prevent word splitting and globbing
  4. Add tests: Include examples demonstrating your feature
  5. Document security: Explain security considerations in comments
  6. Follow conventions: Use the s.namespace.function naming pattern
# Before submitting:
make build
shellcheck functions/*.sksh boot.sksh examples/scripts/*.sksh

πŸ“„ License

MIT Β© trentas


πŸ™ Acknowledgments

Built with ❀️ by developers who got tired of writing the same bash boilerplate.

Special thanks to:

  • The shellcheck project for making bash code safer
  • Everyone who contributed security fixes
  • All the production environments running smack

Ready to smack your bash scripts into shape? Get started now! 🎯

git clone https://github.com/trentas/smack.git && cd smack && make install

About

🧨 Smack your bash up - Create scripts Safer, Better, Faster, Stronger

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published