A comprehensive coding standard for modern Bash 5.2+ scripts, designed for consistency, robustness, and maintainability.
Version 1.0.2 | 12 Sections | 101 Rules | 13 Subcommands
This repository contains the canonical Bash coding standards developed by Okusi Associates and adopted by the Indonesian Open Technology Foundation (YaTTI).
Bash is a battle-tested, sophisticated programming language deployed on virtually every Unix-like system. When wielded with discipline and proper engineering principles, Bash delivers production-grade solutions for system automation, data processing, and infrastructure orchestration. This standard codifies that discipline.
- Targets Bash 5.2+ exclusively (not a compatibility standard)
- Enforces strict error handling with
set -euo pipefail - Requires explicit variable declarations with type hints
- Mandates ShellCheck compliance
- Defines standard utility functions for consistent messaging
- 12 comprehensive sections covering all aspects of Bash scripting
- AI-powered compliance checking and rule compression via Claude
- Human developers writing production-grade Bash scripts
- AI assistants generating or analyzing Bash code
- DevOps engineers and system administrators
- Organizations needing standardized scripting guidelines
A minimal BCS-compliant script:
#!/usr/bin/env bash
# Brief description of the script
set -euo pipefail
shopt -s inherit_errexit shift_verbose
VERSION='1.0.0'
SCRIPT_PATH=$(realpath -e -- "$0")
SCRIPT_DIR=${SCRIPT_PATH%/*}
SCRIPT_NAME=${SCRIPT_PATH##*/}
readonly -- VERSION SCRIPT_PATH SCRIPT_DIR SCRIPT_NAME
error() { >&2 printf '%s: %s\n' "$SCRIPT_NAME" "$*"; }
die() { (($# > 1)) && error "${@:2}"; exit "${1:-1}"; }
main() {
echo "Hello from $SCRIPT_NAME v$VERSION"
}
main "$@"
#fin| Requirement | Version | Check Command |
|---|---|---|
| Bash | 5.2+ | bash --version |
| ShellCheck | 0.8.0+ | shellcheck --version |
| Claude CLI | Latest | claude --version (optional, for AI features) |
Install ShellCheck:
# Ubuntu/Debian
sudo apt install shellcheck
# macOS
brew install shellcheck
# Fedora/RHEL
sudo dnf install ShellCheckQuick Install (one-liner):
git clone https://github.com/OkusiAssociates/bash-coding-standard.git && cd bash-coding-standard && sudo make installStandard Installation:
git clone https://github.com/OkusiAssociates/bash-coding-standard.git
cd bash-coding-standard
# Run directly (development mode)
./bcs
# Or install system-wide
sudo make installMakefile Targets:
sudo make install # Install to /usr/local (default)
sudo make PREFIX=/usr install # Install to /usr (system-wide)
sudo make uninstall # Remove installation
make help # Show all targets
make check-deps # Check optional dependencies# View the standard
bcs # Auto-detect best viewer
bcs display --cat # Plain text output
# Generate a BCS-compliant script
bcs template -t complete -n myscript -o myscript.sh -x
# Check script compliance (requires Claude CLI)
bcs check myscript.sh
# Look up BCS rules
bcs codes # List all 101 rule codes
bcs decode BCS0102 -p # View specific rule content
bcs search "readonly" # Search the standardThe bcs toolkit provides 13 subcommands for working with the Bash Coding Standard.
View the coding standard document with multiple output formats.
bcs # Auto-detect viewer (md2ansi → less → cat)
bcs display # Explicit display commandOptions:
| Option | Description |
|---|---|
-c, --cat |
Force plain text output (bypass md2ansi) |
-a, --md2ansi |
Force md2ansi output |
-j, --json |
Output as JSON |
-b, --bash |
Export as bash variable declaration |
-s, --squeeze |
Squeeze consecutive blank lines |
-h, --help |
Show help |
Legacy compatibility: bcs -c, bcs -j, bcs -b still work.
Display project information, statistics, and metadata.
bcs about # Default: project info + philosophy + quick stats
bcs about --stats # Statistics only
bcs about --json # JSON output for scriptingOptions:
| Option | Description |
|---|---|
-s, --stats |
Show statistics only |
-l, --links |
Show documentation links |
-v, --verbose |
Show all information |
-q, --quote |
Show philosophy quote only |
--json |
JSON output |
-h, --help |
Show help |
Generate BCS-compliant script templates instantly.
bcs template # Generate basic template to stdout
bcs template -t complete -o script.sh -x # Complete template, executable
bcs template -t library -n mylib # Library templateOptions:
| Option | Description |
|---|---|
-t, --type TYPE |
Template type: minimal, basic, complete, library |
-n, --name NAME |
Script name (sanitized for bash) |
-d, --description DESC |
Script description |
-v, --version VERSION |
Version string (default: 1.0.0) |
-o, --output FILE |
Output file (default: stdout) |
-x, --executable |
Make output file executable |
-f, --force |
Overwrite existing file |
-h, --help |
Show help |
Template Types:
| Type | Lines | Contents |
|---|---|---|
minimal |
~13 | set -euo pipefail, error(), die(), main() |
basic |
~27 | + metadata, messaging functions, readonly |
complete |
~104 | + colors, arg parsing, all utility functions |
library |
~38 | Sourceable pattern, function exports (no set -e) |
Placeholders: {{NAME}}, {{DESCRIPTION}}, {{VERSION}}
AI-powered compliance checking using Claude CLI.
bcs check myscript.sh # Comprehensive check
bcs check --strict deploy.sh # Strict mode (for CI/CD)
bcs check --format json script.sh # JSON outputOptions:
| Option | Description |
|---|---|
-s, --strict |
Strict mode (warnings become violations) |
-f, --format FORMAT |
Output: text, json, markdown, bcs-json |
-q, --quiet |
Suppress non-error output |
--codes CODE1,CODE2 |
Validate only specific BCS codes |
--sections N1,N2 |
Validate only sections 1-12 |
--tier TIER |
Documentation tier: abstract (fast), complete (thorough) |
--severity LEVEL |
Filter: all, violations, warnings |
--claude-cmd CMD |
Custom Claude command path |
--append-prompt TEXT |
Additional system prompt |
--allowed-tools TOOLS |
Restrict Claude tools |
--add-dir PATH |
Add directory for Claude context |
--skip-permissions |
Skip permission checks |
-h, --help |
Show help |
Exit Codes: 0 = Compliant, 1 = Warnings only, 2 = Violations
Requirements: Claude CLI (claude command) in PATH
AI-powered compression of BCS rule files (developer mode).
bcs compress # Report oversized files only
bcs compress --regenerate # Regenerate all tiers
bcs compress --regenerate --context-level abstract # Recommended
bcs compress --regenerate --file path/to/rule.complete.md # Single fileOptions:
| Option | Description |
|---|---|
--report-only |
Report oversized files only (default) |
--regenerate |
Delete and regenerate compressed files |
--file FILE |
Process single .complete.md file (v1.0.1+) |
--tier TIER |
Process tier: summary or abstract |
--force |
Force regeneration (bypass timestamp checks) |
--summary-limit N |
Max summary size in bytes (default: 10000) |
--abstract-limit N |
Max abstract size in bytes (default: 1500) |
--context-level LEVEL |
Context: none, toc, abstract, summary, complete |
-n, --dry-run |
Preview changes without writing |
-q, --quiet |
Quiet mode |
-v, --verbose |
Verbose mode (default) |
--claude-cmd CMD |
Claude CLI path |
-h, --help |
Show help |
Context Levels:
none- Fastest, each rule in isolation (default)abstract- Recommended, cross-rule deduplication (~83KB context)complete- Maximum context awareness (~520KB)
List all BCS rule codes from the data/ directory.
bcs codes # List all codes
bcs codes | wc -l # Count rules (101)
bcs codes | grep variable # Find variable-related rulesOutput Format: BCS{code}:{shortname}:{title}
Example:
BCS010201:dual-purpose:Dual-Purpose Scripts (Executable and Sourceable)
BCS0103:metadata:Script Metadata
BCS0205:readonly-after-group:Readonly After Group
Regenerate BASH-CODING-STANDARD.md from the data/ directory.
bcs generate # Generate to stdout (default tier)
bcs generate --canonical # Regenerate all canonical files
bcs generate -t abstract # Generate abstract tier onlyOptions:
| Option | Description |
|---|---|
-t, --type TYPE |
Tier: complete, summary, abstract, rulet |
-o, --output FILE |
Output to specific file |
--canonical |
Generate all four tiers to canonical files |
-x, --exclude CODES |
Exclude BCS codes (comma-separated) |
-f, --force |
Force regeneration ignoring timestamps |
-h, --help |
Show help |
Exclusion Examples:
-x 0103- Exclude BCS0103-x BCS01- Exclude entire section 1-x 0103,0201,010201- Multiple exclusions
Extract concise rulets from complete.md files using AI.
bcs generate-rulets 02 # Generate for section 02
bcs generate-rulets variables # Same - by category name
bcs generate-rulets --all # Generate for all 12 categories
bcs generate-rulets --all --force # Force regenerationOptions:
| Option | Description |
|---|---|
-a, --all |
Generate rulets for all 12 categories |
-f, --force |
Force regeneration of existing files |
--agent-cmd PATH |
Path to bcs-rulet-extractor agent |
-h, --help |
Show help |
Output: data/{NN}-{category}/00-{category}.rulet.md
Rulet Format: [BCS####] Concise rule statement with code examples.
Search within the coding standard document.
bcs search "readonly" # Basic search
bcs search -i "SET -E" # Case-insensitive
bcs search -C 10 "declare -fx" # With 10 context linesOptions:
| Option | Description |
|---|---|
-i, --ignore-case |
Case-insensitive search |
-C NUM |
Show NUM lines of context (default: 3) |
-h, --help |
Show help |
Resolve BCS codes to file locations or print rule content.
bcs decode BCS0102 # Show file path (default tier)
bcs decode BCS0102 -p # Print rule content
bcs decode BCS01 BCS08 -p # Multiple codes with separators
vim $(bcs decode BCS0205) # Open in editorOptions:
| Option | Description |
|---|---|
-a, --abstract |
Show abstract tier |
-s, --summary |
Show summary tier |
-c, --complete |
Show complete tier |
-r, --rulet |
Show rulet tier (section-level only) |
-p, --print |
Print file contents instead of path |
--all |
Show all three tier locations |
--relative |
Output relative to repository root |
--basename |
Output only filename |
--exists |
Exit 0 if code exists, 1 if not |
-h, --help |
Show help |
Code Formats:
- Section:
BCS01(2 digits) - Rule:
BCS0102(4 digits) - Subrule:
BCS010201(6 digits)
List all 12 sections of the standard.
bcs sections # List all sectionsOutput:
1. Script Structure & Layout
2. Variables & Data Types
3. Strings & Quoting
...
12. Style & Development
Set or show the default documentation tier.
bcs default # Show current default tier
bcs default complete # Set default to complete tier
bcs default --list # List all available tiersOptions:
| Option | Description |
|---|---|
-l, --list |
List all available tiers (marks current with *) |
-h, --help |
Show help |
Tiers: complete, summary, abstract, rulet
Show help for commands.
bcs help # General help with all commands
bcs help check # Help for specific subcommand
bcs check --help # Same as aboveThe Bash Coding Standard is organized into 12 comprehensive sections:
| # | Section | Key Topics |
|---|---|---|
| 1 | Script Structure & Layout | 13-step mandatory structure, shebang, metadata, function organization |
| 2 | Variables & Data Types | Declarations, scoping, naming, readonly patterns, arrays, parameter expansion |
| 3 | Strings & Quoting | Single vs double quotes, mixed quoting, here-docs |
| 4 | Functions & Libraries | Definition patterns, organization, export, library patterns |
| 5 | Control Flow | Conditionals, case statements, loops, arithmetic |
| 6 | Error Handling | set -e, exit codes, traps, return value checking |
| 7 | I/O & Messaging | Standard messaging functions, colors, TUI basics |
| 8 | Command-Line Arguments | Parsing patterns, short option support |
| 9 | File Operations | Testing, wildcards, process substitution |
| 10 | Security | SUID, PATH, eval, IFS, input sanitization, temp files |
| 11 | Concurrency & Jobs | Background jobs, parallel execution, timeouts |
| 12 | Style & Development | Formatting, debugging, dry-run, testing |
Every BCS-compliant script follows this structure:
- Shebang:
#!/usr/bin/env bash - ShellCheck directives (if needed):
#shellcheck disable=SC#### - Brief description comment: One-line purpose
- Strict mode:
set -euo pipefail(mandatory) - Shell options:
shopt -s inherit_errexit shift_verbose extglob nullglob - Script metadata: VERSION, SCRIPT_PATH, SCRIPT_DIR, SCRIPT_NAME →
readonly -- - Global variable declarations: With explicit types
- Color definitions: If terminal output needed
- Utility functions: Messaging, helpers
- Business logic functions: Core functionality
main()function: Required for scripts >40 lines- Script invocation:
main "$@" - End marker:
#fin(mandatory)
Variable Expansion:
# Default: no braces
echo "$var"
# Use braces when required:
echo "${var##pattern}" # Parameter expansion
echo "${var:-default}" # Default values
echo "${array[@]}" # Arrays
echo "${var1}${var2}" # ConcatenationQuoting:
# Single quotes for static strings
info 'Processing files...'
# Double quotes when variables needed
info "Processing $count files"
# Always quote in conditionals
[[ -f "$file" ]]Arithmetic:
# Correct increment
i+=1
((i+=1))
# WRONG - fails with set -e when i=0
((i++))Error Output:
# Place >&2 at beginning
>&2 echo "error message"Process Substitution:
# Prefer this (avoids subshell issues)
while IFS= read -r line; do
count+=1
done < <(command)
# Avoid pipes to while (subshell loses variables)
command | while read -r line; do count+=1; doneEvery compliant script should implement these messaging functions:
_msg() { ... } # Core message function using FUNCNAME
vecho() { ... } # Verbose output (respects VERBOSE)
success() { ... } # Success messages (green ✓)
warn() { ... } # Warnings (yellow ▲)
info() { ... } # Info messages (cyan ◉)
debug() { ... } # Debug output (respects DEBUG)
error() { ... } # Unconditional error output (red ✗)
die() { ... } # Exit with error message
yn() { ... } # Yes/no promptOrganize functions bottom-up:
- Messaging functions (lowest level)
- Documentation functions (help, usage)
- Helper/utility functions
- Validation functions
- Business logic functions
- Orchestration/flow functions
main()function (highest level)
Rationale: Each function can safely call functions defined above it.
The standard exists in four tiers with decreasing detail levels:
| Tier | Lines | Size | Purpose |
|---|---|---|---|
| complete | ~24,333 | 610 KB | Authoritative source - full detail, all examples |
| summary | ~15,117 | 373 KB | Condensed - key rules, essential examples (default) |
| abstract | ~4,439 | 109 KB | High-level overview - rules only |
| rulet | ~714 | 72 KB | Concise rule list - one per section |
.complete.md (SOURCE - manually edited)
↓ bcs compress
.summary.md (DERIVED - ~62% of complete)
↓ bcs compress
.abstract.md (DERIVED - ~29% of complete)
Separate: .rulet.md (Extracted concise rules)
The default tier is controlled by the data/BASH-CODING-STANDARD.md symlink:
- Currently points to
.summary.md - Change with:
bcs default complete
# Edit source (complete tier only)
vim $(bcs decode BCS0205 -c)
# Regenerate derived tiers
bcs compress --regenerate
# Rebuild canonical files
bcs generate --canonicalBCS{section}{rule}[{subrule}] - All numbers are two-digit zero-padded
| Code | Level | Example |
|---|---|---|
BCS01 |
Section | Script Structure & Layout |
BCS0102 |
Rule | Shebang and Initial Setup |
BCS010201 |
Subrule | Dual-Purpose Scripts |
data/01-script-structure/ → BCS01 (Section)
├── 00-section.*.md → BCS0100 (Section intro)
├── 02-shebang.*.md → BCS0102 (Rule)
├── 02-shebang/01-dual-purpose.*.md → BCS010201 (Subrule)
└── 03-metadata.*.md → BCS0103 (Rule)
The BCS/ directory provides numeric-indexed symlinks for quick lookups:
BCS/
├── 01/ → 01-script-structure/
│ ├── 00.summary.md → Section intro
│ ├── 02.summary.md → Rule 02 (Shebang)
│ └── 02/01.summary.md → Subrule 01 (Dual-Purpose)
└── 02/ → 02-variables/
bcs codes # List all codes
bcs decode BCS0102 # Get file path
bcs decode BCS0102 -p # Print content
bcs decode BCS0102 --all # Show all tiersbash-coding-standard/
├── bcs # Main CLI toolkit (v1.0.2, 161KB)
├── bash-coding-standard # Symlink → bcs
├── bcs.1 # Man page (19KB)
├── bcs.bash_completion # Bash completion (9KB)
├── Makefile # Installation targets
├── CLAUDE.md # AI assistant instructions
├── README.md # This file
├── LICENSE # CC BY-SA 4.0
│
├── data/ # Standard source files
│ ├── BASH-CODING-STANDARD.md # Symlink → default tier
│ ├── BASH-CODING-STANDARD.*.md # Compiled standards (4 tiers)
│ ├── 00-header.*.md # Header files (4 tiers)
│ ├── 01-script-structure/ # Section 1
│ ├── 02-variables/ # Section 2
│ ├── ... # Sections 3-12
│ └── templates/ # Script templates (4 files)
│
├── BCS/ # Numeric-indexed symlinks
├── lib/ # Bundled tools (15 utilities, ~544KB)
├── tests/ # Test suite (34 files, 460+ tests)
├── workflows/ # Maintenance scripts (8 files)
├── examples/ # Production examples (3 scripts)
├── builtins/ # Optional C builtins (5 commands)
├── docs/ # Additional documentation
└── .github/workflows/ # CI/CD (3 workflows)
Each section directory follows this structure:
data/{NN}-{category}/
├── 00-section.complete.md # Section introduction
├── 00-section.summary.md
├── 00-section.abstract.md
├── 00-{category}.rulet.md # Concise rules for section
├── {NN}-{rule}.complete.md # Rule (canonical source)
├── {NN}-{rule}.summary.md # Rule (derived)
├── {NN}-{rule}.abstract.md # Rule (derived)
└── {NN}-{rule}/ # Subrule directory (if any)
└── {NN}-{subrule}.*.md
Four BCS-compliant templates are available in data/templates/:
| Template | Lines | Use Case |
|---|---|---|
minimal.sh.template |
~13 | Quick scripts, bare essentials |
basic.sh.template |
~27 | Standard scripts with metadata |
complete.sh.template |
~104 | Full toolkit, production scripts |
library.sh.template |
~38 | Sourceable libraries |
minimal: set -euo pipefail, error(), die(), main()
basic: + VERSION, SCRIPT_PATH, SCRIPT_DIR, SCRIPT_NAME, _msg()
complete: + colors, VERBOSE/DEBUG flags, full messaging (info, warn, success, debug), argument parsing with --help/--version
library: Sourceable pattern, no set -e, declare -fx exports, namespace prefix
# Quick script
bcs template -t minimal -o quick.sh -x
# Production script with all utilities
bcs template -t complete -n deploy -d "Production deployment" -v 2.0.0 -o deploy.sh -x
# Sourceable library
bcs template -t library -n utils -o lib-utils.shThe lib/ directory contains 15 vendored utilities (~544KB total):
| Category | Tools | Purpose |
|---|---|---|
| Markdown | md2ansi, md, mdheaders | Terminal rendering, header manipulation |
| Text | trim, remblanks, post_slug | String processing, slug generation |
| System | whichx, dux, printline, bcx | Command location, disk analysis, calculator |
| Development | timer, hr2int | Timing, number conversion |
| BCS Agents | bcs-rulet-extractor, bcs-compliance | AI integration |
All tools are installed to /usr/local/bin via make install.
Full documentation: See lib/README.md
The bcs script can be used in two modes:
Executed Mode (./bcs or bcs):
# Standard CLI usage
bcs display
bcs check script.sh
bcs template -t complete -o test.sh- Strict mode enabled:
set -euo pipefail - Dispatcher runs subcommands
- Returns exit codes
Sourced Mode (source bcs):
# Use bcs functions in your scripts
source /usr/local/bin/bcs
# Access pre-loaded standard
echo "$BCS_MD" | head -20
# Use internal functions
cmd_codes
cmd_decode BCS0102- Does NOT set
set -e(doesn't affect caller) - All
cmd_*functions available BCS_MDvariable pre-loaded
The toolkit searches for files in standard locations:
For BASH-CODING-STANDARD.md:
- Script directory (development)
$(PREFIX)/share/yatti/bash-coding-standard/(custom install)/usr/local/share/yatti/bash-coding-standard/(local install)/usr/share/yatti/bash-coding-standard/(system install)
The subcommand architecture uses a dispatcher pattern:
main() {
local subcmd=${1:-display}
shift || true
case "$subcmd" in
display) cmd_display "$@" ;;
about) cmd_about "$@" ;;
template) cmd_template "$@" ;;
# ... 13 commands total
*) die 1 "Unknown command: $subcmd" ;;
esac
}-
Create function:
cmd_foo() { ... }; declare -fx cmd_foo- Find location:
grep -n '^cmd_' bcs | tail -5
- Find location:
-
Add to dispatcher: Add case pattern in main dispatch
- Find location:
grep -n 'case "$subcmd"' bcs
- Find location:
-
Add to help: Update help routing and command list
- Find location:
grep -n 'show_help\|^Commands:' bcs
- Find location:
-
Create test file:
tests/test-subcommand-foo.sh
| Metric | Value |
|---|---|
| Test files | 34 |
| Total tests | 460+ |
| Pass rate | 100% |
| Assertions | 21 types |
./tests/run-all-tests.sh # Run all test suites
./tests/test-subcommand-check.sh # Run specific test file
./tests/coverage.sh # Analyze test coverageThe test framework (tests/test-helpers.sh) provides 21 assertion functions:
Basic Assertions:
assert_equals- Compare two valuesassert_contains- Check substring presenceassert_not_contains- Check substring absenceassert_not_empty- Verify non-empty value
Exit Code Assertions:
assert_exit_code- Check specific exit codeassert_success- Verify exit code 0assert_failure- Verify non-zero exit
File Assertions:
assert_file_exists- Verify file existsassert_dir_exists- Verify directory existsassert_file_executable- Verify file is executableassert_file_contains- Check file content
Numeric Assertions:
assert_zero- Verify value is 0assert_not_zero- Verify value is non-zeroassert_greater_than- Compare valuesassert_less_than- Compare valuesassert_lines_between- Check line count range
Pattern Assertions:
assert_regex_match- Match regex pattern
Organization:
test_section- Start named test sectiontest_summary- Display pass/fail counts
Subcommand Tests (13 files):
test-subcommand-display.sh test-subcommand-about.sh
test-subcommand-template.sh test-subcommand-check.sh
test-subcommand-compress.sh test-subcommand-codes.sh
test-subcommand-generate.sh test-subcommand-generate-rulets.sh
test-subcommand-search.sh test-subcommand-decode.sh
test-subcommand-sections.sh test-subcommand-default.sh
test-subcommand-dispatcher.shIntegration Tests:
test-integration.sh test-execution-modes.sh
test-environment.sh test-tier-system.sh
test-data-structure.sh test-self-compliance.shWorkflow Tests:
test-workflow-add.sh test-workflow-modify.sh
test-workflow-delete.sh test-workflow-compress.sh
test-workflow-generate.sh test-workflow-validate.sh# Validate changes before commit
shellcheck -x bcs && ./tests/run-all-tests.sh
# After modifying rules
bcs compress --regenerate && bcs generate --canonical
# Verify BCS codes
bcs codes | wc -l # Should be 101| Workflow | Triggers | Purpose |
|---|---|---|
test.yml |
Push, PR | Multi-version Bash testing (5.0, 5.1, 5.2) |
shellcheck.yml |
Push, PR | Static analysis |
release.yml |
Tag push | Automated releases |
The workflows/ directory provides 8 production-ready maintenance scripts:
| Script | Purpose |
|---|---|
01-add-rule.sh |
Create new BCS rules interactively |
02-modify-rule.sh |
Safely edit existing rules |
03-delete-rule.sh |
Delete rules with safety checks |
04-interrogate-rule.sh |
Inspect rules by BCS code |
10-compress-rules.sh |
AI-powered rule compression wrapper |
20-generate-canonical.sh |
Generate canonical BCS files |
30-validate-data.sh |
11 validation checks for data integrity |
40-check-compliance.sh |
Batch compliance checking |
# Add a new rule interactively
./workflows/01-add-rule.sh
# Validate data directory structure
./workflows/30-validate-data.sh
# Interrogate a rule
./workflows/04-interrogate-rule.sh BCS0102 --show-tiers
# Batch compliance check
./workflows/40-check-compliance.sh *.sh --format json- Tier file completeness (.complete, .summary, .abstract)
- BCS code uniqueness (no duplicates)
- File naming conventions
- BCS code format validation
- Section directory naming
- File size limits (summary ≤10KB, abstract ≤1.5KB)
- BCS code markers in files
- #fin markers present
- Markdown structure validity
- Cross-reference validation
- Sequential numbering checks
Three production-ready example scripts demonstrate BCS patterns:
| Script | Size | Demonstrates |
|---|---|---|
production-deploy.sh |
8.1KB | Deployment automation, rollback, health checks |
data-processor.sh |
4.7KB | CSV processing, validation, statistics |
system-monitor.sh |
9.9KB | Resource monitoring, alerts, logging |
production-deploy.sh:
- Complete 13-step script structure
- Dry-run mode implementation
- User confirmation prompts
- Rollback capability
- Health check integration
- Error handling with traps
data-processor.sh:
- Array operations
- CSV parsing with IFS
- Field validation
- Statistics tracking (counters)
- Color-coded output
system-monitor.sh:
- Continuous monitoring loop
- Threshold-based alerts
- Multiple output levels (VERBOSE, DEBUG)
- Log file integration
- Email notification (configurable)
Location: examples/
Optional high-performance C implementations of common commands:
| Builtin | Speedup | Purpose |
|---|---|---|
basename |
101x | Extract filename |
dirname |
158x | Extract directory |
realpath |
20-100x | Resolve symlinks |
head |
10-30x | First N lines |
cut |
15-40x | Field extraction |
cd builtins
./install.sh --user # User installation
# or
make && sudo make install # System-wideNote: Not required for BCS compliance - purely optional performance enhancement.
Full documentation: See builtins/README.md
BCS Section 12 defines critical security practices:
| Rule | Requirement |
|---|---|
| No SUID/SGID | Never use SUID/SGID in Bash scripts |
| PATH validation | Lock down PATH or validate it early |
| Avoid eval | Never use eval with untrusted input |
| Input sanitization | Validate all external inputs |
| Explicit paths | Use rm ./* not rm * for wildcards |
| Readonly constants | Use readonly for all constants |
| Argument separator | Always use -- before file arguments |
# Validate PATH
[[ "$PATH" == /usr/local/bin:/usr/bin:/bin ]] || die 1 'Invalid PATH'
# Sanitize input
[[ "$input" =~ ^[a-zA-Z0-9_-]+$ ]] || die 1 'Invalid input'
# Safe file operations
rm -- "$file" # Use -- separator
rm ./*.tmp # Explicit path for wildcards
# Prevent injection
printf '%s\n' "$user_input" # printf, not echoShellCheck is mandatory for BCS compliance:
# Run ShellCheck
shellcheck -x script.sh
# Document exceptions with comments
#shellcheck disable=SC2155 # Intentional local assignment
local -r foo=$(command)"command not found: bcs"
# Check if installed
which bcs || echo "Not installed"
# If using development mode, use full path
./bcs
# Or install system-wide
sudo make install"BASH-CODING-STANDARD.md not found"
# Check symlink
ls -la data/BASH-CODING-STANDARD.md
# Regenerate if missing
bcs generate --canonical"Claude CLI not found" (for check/compress)
# Install Claude Code CLI
# See: https://claude.com/code
# Or specify custom path
bcs check --claude-cmd /path/to/claude script.shShellCheck failures
# Run with verbose output
shellcheck -x -f gcc script.sh
# Check specific error codes
# https://www.shellcheck.net/wiki/SCxxxxTests failing
# Run specific test for debugging
./tests/test-subcommand-check.sh
# Check test coverage
./tests/coverage.shbcs help # General help
bcs help <command> # Command-specific help
bcs about # Project informationContributions are welcome! Please ensure:
- All scripts pass ShellCheck:
shellcheck -x script.sh - Tests pass:
./tests/run-all-tests.sh - Follow BCS patterns in all contributions
- Update documentation for new features
- ShellCheck - Static analysis tool
- Google Shell Style Guide - Compatible where applicable
- Bash Reference Manual - Official documentation
This project is licensed under CC BY-SA 4.0 (Creative Commons Attribution-ShareAlike 4.0 International).
See LICENSE for details.
- Developed by: Okusi Associates
- Adopted by: Indonesian Open Technology Foundation (YaTTI)
- Philosophy: "This isn't just a coding standard - it's a systems engineering philosophy applied to Bash." — Biksu Okusi
Updated: 2026-01-01 | Version 1.0.2