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.
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 validationsmack 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)git clone https://github.com/trentas/smack.git
cd smack
make installCreate 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 loggingRun it:
chmod +x hello.sksh
./hello.skshOutput:
INFO hello.sksh:main:4 Hello, smack! π
NOTICE hello.sksh:main:5 Processing...
DEBUG hello.sksh:main:6 running: ls -la
- 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
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
# 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#!/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!)# 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# 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"#!/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#!/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!"#!/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"| 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 |
| 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) |
| 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 |
| 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) |
| 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 |
| Function | Description |
|---|---|
s.email.send "SUBJECT" |
Sends email from stdin with sanitization |
s.print.slack LEVEL "msg" |
Slack notification with validation |
| 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) |
- 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!)
β
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
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.
#!/usr/bin/env smack
# Override defaults
s_config_debug="no" # Disable debug output
s_config_syslog_facility="local5" # Change syslog facility
# Your script logic# 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#!/bin/bash
# Source smack manually in existing scripts
source /usr/local/bin/smack
s.print.log info "Now using smack features!"smack takes security seriously. All recent security enhancements:
- β
Password Security: Uses
MYSQL_PWDenvironment variable (not visible inps) - β 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 USERsyntax - β Webhook Validation: Slack URLs are validated before use
- β Timeout Protection: Network operations have timeouts
See full security audit: SECURITY_FIXES.md
Contributions are welcome! Please:
- Run shellcheck: All code must pass
shellcheckwith zero warnings - Validate inputs: Always validate user inputs
- Use proper quoting: Prevent word splitting and globbing
- Add tests: Include examples demonstrating your feature
- Document security: Explain security considerations in comments
- Follow conventions: Use the
s.namespace.functionnaming pattern
# Before submitting:
make build
shellcheck functions/*.sksh boot.sksh examples/scripts/*.skshMIT Β© trentas
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