Skip to content

Repository files navigation

Bash Coding Standard (BCS)

Concise, actionable coding rules for Bash 5.2+

Designed by Okusi Associates for the Indonesian Open Technology Foundation (YaTTI).

Quickstart

git clone https://github.com/Open-Technology-Foundation/bash-coding-standard.git
cd bash-coding-standard && sudo make install
bcs # View the standard
bcs template -t complete -n deploy -o deploy.sh -x # Scaffold a script
bcs check deploy.sh # AI-powered compliance check
bcs codes # List all 112 BCS rule codes

You now have:

ToolPurpose
bcsCLI for the standard (display / template / check / codes / generate)
bcscheckConvenience shim for bcs check (defaults configured in bcs.conf)
man bcs, man BCS-bashManpages for the CLI and a strict-mode Bash 5.2 reference

For AI Readers

Programmatic anchors for machine consumption:

ResourcePath / CommandUse
Standard documentdata/BASH-CODING-STANDARD.mdSingle assembled doc; ## BCS#### headers
Section sourcesdata/01-*.md ... data/12-*.mdEdit these, never the assembled doc
Rule codesbcs codes / bcs codes -E BCSddddList all, or explain one
AI tooling inventoryai-agents/AGENTS.mdFlat inventory of agents, slash commands, rule snapshots

Canonical command phrasings: bcs check <path>, bcs codes [-E BCSdddd], bcs template -t <type> -n <name> -o <path>, man bcs, man BCS-bash. Rule references in body text use the bare form BCSdddd; in links use [BCSdddd](data/<section>.md).

Why BCS

Bash is a battle-tested programming language deployed on virtually every Unix-like system. When wielded with discipline it delivers production-grade automation, data processing, and infrastructure orchestration. KISS -- keep it simple.

  • Targets Bash 5.2+ exclusively (not a compatibility standard)
  • Strict error handling with set -euo pipefail
  • Explicit variable declarations and scoping
  • Mandatory ShellCheck compliance
  • Standard utility functions for consistent messaging
  • AI-powered compliance checking across five LLM backends

Audience: human developers writing production-grade Bash, AI assistants generating or analysing Bash code, DevOps engineers and organisations needing standardised guidelines.

Installation

git clone https://github.com/Open-Technology-Foundation/bash-coding-standard.git
cd bash-coding-standard
sudo make install # Install to /usr/local (default)
sudo make PREFIX=/usr install # System-wide
sudo make uninstall # Uninstall

Installs the bcs CLI plus per-subcommand shims (bcscheck, bcsdisplay, bcstemplate, bcscodes, bcsgenerate), data files, bash completions, the bcs(1) and BCS-bash(1) manpages, and the rendered HTML reference trees under docs/BCS-bash.html/ and docs/BCS-Bash-Ref.html/.

Prerequisites: Bash 5.2+ (bash --version) and ShellCheck 0.8.0+ (shellcheck --version).

LLM backends (optional, for bcs check) -- at least one of:

BackendRequirement
Anthropic APIANTHROPIC_API_KEY + curl + jq
OpenAI APIOPENAI_API_KEY + curl + jq
Google Gemini APIGOOGLE_API_KEY + curl + jq
Ollama (local or cloud)Running Ollama server
Claude Code CLIclaude installed on PATH

See Compliance Checking for backend trade-offs.

The Standard

The Bash Coding Standard defines 100 substantive rules plus 12 section overviews (112 total codes) across 12 sections in a single ~3,000-line document. Every rule carries examples, a **Tier:** label, and a BCS code (BCSssrr, four digits, zero-padded).

#SectionFocus
1Script Structure & LayoutShebang, strict mode, metadata, function organisation
2Variables & Data TypesType declarations, scoping, naming, arrays
3Strings & QuotingSingle vs double quotes, conditionals, here-docs
4Functions & LibrariesDefinition, organisation, export, library patterns
5Control FlowConditionals, case, loops, arithmetic
6Error HandlingExit codes, traps, return-value checking
7I/O & MessagingStandard messaging functions, colours, TUI
8Command-Line ArgumentsParsing patterns, option bundling, validation
9File OperationsFile testing, wildcards, process substitution
10SecurityPATH, eval avoidance, input sanitisation
11Concurrency & JobsBackground jobs, parallel execution, timeouts
12Style & DevelopmentFormatting, debugging, dry-run, testing

Tier distribution -- bcs check maps tier to severity:

TierCountSeverityBehaviour
core34[ERROR]Real correctness/safety bugs. Non-zero exit if any are found.
recommended44[WARN]Bash hygiene; prevents subtle issues.
style22[WARN]Taste; no correctness impact.
disabled--(silent)Applied only via policy.conf; never reported.

CLI Reference

Subcommands, frequency-ordered:

CommandPurpose
bcs checkAI-powered compliance check against the full standard
bcs templateGenerate BCS-compliant script templates
bcs codesList rule codes; -E BCSdddd to explain one
bcs displayView the standard (default when no subcommand)
bcs generateReassemble BASH-CODING-STANDARD.md from section files (maintainer)
bcs help [CMD]Per-command help

bcs check

bcs check myscript.sh # Default alias 'sonnet' (claude-sonnet-4-6)
bcs check -m opus deploy.sh # Alias-expanded to claude-opus-4-8
bcs check -m gpt5 -e high deploy.sh # OpenAI gpt-5 with reasoning_effort=medium
bcs check -m claude-code:opus ci.sh # Claude Code CLI with the opus alias
bcs check --strict -T core deploy.sh # CI gate: core-only, warnings fatal
bcs check --no-shellcheck myscript.sh # Skip the shellcheck static-analysis prelude
bcs check -j ci.sh | jq '.comments[]'# JSON output (shellcheck json1-style envelope)
bcs check --no-cache myscript.sh # Bypass the result cache (force a fresh LLM call)
bcscheck myscript.sh # Equivalent shim (defaults from bcs.conf)

When shellcheck is on PATH, bcs check prepends its --format=json -x output to the LLM prompt as deterministic static-analysis context (cheap, precise AST-level findings that the LLM would otherwise rediscover). Disable per-call with --no-shellcheck or globally via BCS_SHELLCHECK=0 in bcs.conf.

Successful results are cached under ${XDG_CACHE_HOME:-~/.cache}/bcs/, keyed on script content, standard content, model, effort, and filters — re-checking an unchanged script returns instantly at zero API cost. Bypass per-call with --no-cache or globally via BCS_CACHE=0. On the Anthropic backend the standard is additionally sent with prompt caching (cache_control: ephemeral), so repeated fresh checks within the server-side cache window pay a fraction of the input-token cost.

bcs template

bcs template -t complete -n deploy -d 'Deploy script' -o deploy.sh -x
TypeLinesUse
minimal~18Bare essentials
basic~43Standard with metadata (default)
complete~112Full toolkit (main, args, messaging, cleanup)
library~37Sourceable library (no main)

bcs codes

bcs codes # All rules, tier-decorated
bcs codes -T core # Only core-tier rules (34)
bcs codes -E BCS0101 # Explain one rule
bcs codes -p # Plain output (no tier decoration)

bcs display & bcs generate

bcs (no args) renders the standard via md2ansi + less in a terminal. Flags: -c plain, -S symlink the standard into cwd, -f print its path. bcs generate rebuilds data/BASH-CODING-STANDARD.md from the data/[0-9]*.md section files -- maintainer-only; never edit the assembled document directly.

Compliance Checking

bcs check analyses a script with an LLM and reports findings keyed to BCS codes. The backend is resolved entirely from the -m model name -- there is no separate --backend flag.

Backend routing

The -m value is alias-expanded then routed by name prefix. Legacy tier keywords (fast/balanced/thorough) exit non-zero with a migration hint.

-m valueBackendNotes
claude-* (e.g. claude-opus-4-8)Anthropic APIPass-through
gemini-* (e.g. gemini-2.5-pro)Google Gemini APIPass-through
gpt-* / o[0-9]* (e.g. gpt-5, o3-mini)OpenAI APIPass-through
claude-codeClaude Code CLIBCS_MODEL or sonnet default
claude-code:<alias-or-model>Claude Code CLISuffix alias-expanded
anything else (e.g. minimax-m2:cloud)Local OllamaPass-through

▲ Local Ollama models whose names match claude-*, gemini-*, gpt-*, or o[0-9]* are unreachable through -m -- rename the local model.

Built-in model aliases

Set MODEL_ALIASES[name]=canonical-id in bcs.conf to extend or override.

AliasCanonical IDBackend
opusclaude-opus-4-8Anthropic
sonnet (default)claude-sonnet-4-6Anthropic
haikuclaude-haiku-4-5Anthropic
flashgemini-2.5-flashGoogle
progemini-2.5-proGoogle
flash-litegemini-2.5-flash-liteGoogle
gpt5gpt-5OpenAI
gpt5-minigpt-5-miniOpenAI
qwenqwen3.5:14bOllama
qwen-smallqwen3.5:9bOllama

Effort levels

-e sets the max output tokens AND the thinking/reasoning budget on capable models. Anthropic thinking.budget_tokens auto-applies on opus and sonnet-4-6/4-7; OpenAI reasoning_effort auto-applies on o[0-9]* and gpt-5*; Gemini thinkingConfig.thinkingBudget auto-applies on the 2.5 family except flash-lite. Other models silently ignore the budget.

-eMax tokensThinking budgetOpenAI reasoning_effort
low (alias min)40000 (off)minimal
medium (default)80002000low
high240006000medium
xhigh4000012000high
max6400016000high

Recommended defaults

Use caseSetting
Quick sanity check-m gpt5 -e medium
Daily development-m sonnet -e medium
Pre-commit review-m sonnet -e high
Thorough audit-m sonnet -e max
Pre-release audit-m claude-code:opus -e max

Filtering, CI gates, suppression

  • -T <tier> -- only findings at that tier (e.g. bcscheck -T core deploy.sh as a CI gate).
  • -M <tier> -- that tier or stricter (-M recommended excludes style).
  • --strict -- treat warnings as violations (non-zero exit on any finding).
  • -j / --json -- emit a single {source, meta, comments} JSON object on stdout, schema-compatible with shellcheck --format=json1, for CI ingestion. Exit 5 if the LLM emits invalid JSON (raw response preserved in the dump file).
  • #bcscheck disable=BCSdddd on its own line suppresses a rule for the next command, function, or { ... } block -- same scope rules as shellcheck directives.

Accuracy data -- backend accuracy is measured against four BCS-compliant scripts (cln, md2ansi, which, tests/accuracy/bcs-check-accuracy.sh) across multiple models and effort levels. See tests/accuracy/LLM-ACCURACY.md for the current scoring matrix and refresh date.

Customisation

Policy Overrides (policy.conf)

Reclassify or disable any rule:

# ~/.config/bcs/policy.conf -- or .bcs/policy.conf per repo
BCS0301 = style # downgrade single-quote dogma
BCS0109 = disabled # silence #fin end-marker noise
BCS9801 = core # classify a user rule

Cascade, later wins: /etc/bcs/policy.conf~/.config/bcs/policy.conf.bcs/policy.conf. Parsed with a strict regex, never sourced as shell. See bcs.policy.sample.

Custom Rules (BCS9800--BCS9899)

The BCS98xx namespace is reserved for user rules. Place markdown files (same structure as any BCS rule) at data/98-user.md (single file) or data/98-user.d/*.md (drop-in directory); both may be symlinks. bcs generate splices them into BASH-CODING-STANDARD.md after section 12. Both paths are .gitignored so user rules never ship upstream.

Configuration (bcs.conf)

Cascading bash-sourced config, later wins: /etc/bcs.conf/etc/bcs/bcs.conf/usr/local/etc/bcs/bcs.conf~/.config/bcs/bcs.conf (XDG).

BCS_MODEL=sonnet # alias or canonical model ID
BCS_EFFORT=medium # min, low, medium, high, xhigh, max
BCS_STRICT=0 # 0 or 1
MODEL_ALIASES[mycloud]=minimax-m2:cloud # extend or override the alias map
EFFORT_THINKING[xhigh]=12000 # tune Anthropic/Google thinking budget

CLI flags override config; config overrides environment. See bcs.conf.sample for all options including MODEL_ALIASES, EFFORT_TOKENS, EFFORT_THINKING, and EFFORT_REASONING overrides.

Examples

Standalone Scripts

examples/ contains exemplar BCS-compliant scripts:

ScriptLinesDemonstrates
cln243File operations, argument parsing, arrays
md2ansi1424Large-scale text processing, ANSI formatting
which111Dual-purpose script pattern

Reference Codebase Library & Templates

examples/lib/ is a curated set of working, BCS-compliant reference codebases organised by domain (file/, math/, str/, sys/, time/) -- see the index for an annotated tour of each project. Generate fresh BCS-compliant skeletons with bcs template -t {minimal,basic,complete,library} (see CLI Reference).

AI Tooling (ai-agents/)

The ai-agents/ package bundles BCS-aware agents, slash commands, and rule snapshots for Claude Code, opencode, and codex. Drop them into ~/.claude/, ~/.config/opencode/, or ~/.codex/ to give any AI session BCS-aware scaffolding, auditing, and ShellCheck remediation.

ComponentInventoryUse
Agentsbash-expert, bcs-auditor, script-scaffolder, shellcheck-fixer, documentation-writerAutonomous BCS-aware sub-agents
Slash commands/audit-bash, /bcs-audit, /bcs-codes, /fix-shellcheck, /scaffold, /purpose-functionality-usage, /update-docs, /update-internal-docsSingle-shot operations
Rule snapshotsbash-coding-standard.md, coding-principles.md, documentation.md, ...Drop-in rule files

See ai-agents/AGENTS.md for the flat file inventory.

Claude Code integration (skills/, enterprise install)

One entry point per checking function — no overlap:

FunctionEntry pointMechanism
Static lintshellcheckCLI
Deep BCS checkbcscheck / bcs checkCLI, LLM backend
In-session BCS checkbcscheck skillClaude reads BASH-CODING-STANDARD.md directly — no CLI, no API keys
Combined CLI audit/bcs-auditRuns shellcheck + bcscheck in parallel
Whole-codebase audit/audit-bash15-section audit prompt, saves AUDIT-BASH.md
ShellCheck remediation/fix-shellcheckFixes SC#### per BCS patterns (per-user, ai-agents/)

The bcscheck skill honours #bcscheck disable= directives and uses shellcheck JSON as static context; for policy.conf tiers, JSON output, or caching use the real bcs check. Sources live in skills/*/SKILL.md and ai-agents/commands/; install machine-wide with sudo make install-claude, remove with sudo make uninstall-claude.

Bash References (BCS-bash, BCS-Bash-Ref)

BCS ships two complementary Bash references, both authored for strict-mode scripting (set -euo pipefail, [[ ]], no backtick substitution, no POSIX/sh-emulation caveats):

ReferenceScopeSourceRendered
BCS-bashRewritten Bash 5.2 manpagedocs/BCS-bash/docs/BCS-bash.html/, man BCS-bash
BCS-Bash-RefAdvanced Bash Reference (25 Parts + Appendices, ~350 leaves)docs/BCS-Bash-Ref/docs/BCS-Bash-Ref.html/
man BCS-bash # Manpage (also: man bcs-bash)
xdg-open docs/BCS-Bash-Ref.html/index.html # Advanced reference (HTML)

The HTML trees are checked-in artefacts. The BCS-Bash-Ref.html/ tree is rebuilt via docs/BCS-Bash-Ref.html.build, which wraps mdview --preserve-tmp and rsyncs the rendered tree into place.

Testing & Self-Compliance

./tests/run-all-tests.sh # Run all suites
./tests/test-subcommand-template.sh # Run a single suite
shellcheck -x bcs bcscheck # Mandatory static check
make test# Full suite shortcut (== ./tests/run-all-tests.sh)
make check # Verify an install (bcs/shims on PATH), not a lint

Self-compliance: the bcs script is itself BCS-compliant. tests/test-self-compliance.sh enforces this structurally on every test run -- it asserts shellcheck -x is clean and that the mandatory structure is present (shebang, strict mode, shopt, main(), #fin, messaging helpers, line-count envelope). The full LLM bcs check bcs is available as a manual deep check but is not run in CI (slow, non-deterministic, requires a backend).

Related Resources

License & Acknowledgments

BCS is dual-licensed to suit the two kinds of material it contains:

  • The BCS CLI tooling (bcs, bcscheck, tests, Makefile, templates, man pages, first-party examples) is licensed under GPL-3.0-or-later.
  • The Bash Coding Standard document (data/*) -- prose, a creative work -- is licensed under CC BY-SA 4.0.
  • Bundled reference implementations under examples/lib/**/ ship with their own per-project LICENSE files (predominantly GPL-3).

See COPYING for a plain-English summary of the split. Every first-party file carries an SPDX-License-Identifier header so tooling (e.g. REUSE) can identify each file's licence unambiguously.

Developed by Okusi Associates for the Indonesian Open Technology Foundation (YaTTI).

About

Comprehensive engineering standard for modern Bash 5.2+ scripts, designed for consistency, robustness, and maintainability. These standards define precise patterns for writing production-grade Bash scripts that are both human-readable and machine-parseable.

Topics

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages