Shell scripting best practices for writing safe, portable, and maintainable bash/sh scripts (formerly shell-scripts). Use when writing, reviewing, or refactoring shell scripts...
Comprehensive best practices guide for shell scripting, designed for AI agents and LLMs. Contains 49 rules across 9 categories, prioritized by impact from critical (safety, portability) to incremental (style). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics.
Reference these guidelines when:
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Safety & Security | CRITICAL | safety- |
6 |
| 2 | Portability | CRITICAL | port- |
5 |
| 3 | Error Handling | HIGH | err- |
8 |
| 4 | Variables & Data | HIGH | var- |
5 |
| 5 | Quoting & Expansion | MEDIUM-HIGH | quote- |
6 |
| 6 | Functions & Structure | MEDIUM | func- |
5 |
| 7 | Testing & Conditionals | MEDIUM | test- |
5 |
| 8 | Performance | LOW-MEDIUM | perf- |
6 |
| 9 | Style & Formatting | LOW | style- |
3 |
safety-command-injection - Prevent command injection from user inputsafety-eval-avoidance - Avoid eval for dynamic commandssafety-absolute-paths - Use absolute paths for external commandssafety-temp-files - Create secure temporary filessafety-suid-forbidden - Never use SUID/SGID on shell scriptssafety-argument-injection - Prevent argument injection with double dashport-shebang-selection - Choose shebang based on portability needsport-avoid-bashisms - Avoid bashisms in POSIX scriptsport-printf-over-echo - Use printf instead of echo for portabilityport-export-syntax - Use portable export syntaxport-test-portability - Use portable test constructserr-strict-mode - Use strict mode for error detectionerr-exit-codes - Use meaningful exit codeserr-trap-cleanup - Use trap for cleanup on exiterr-stderr-messages - Send error messages to stderrerr-pipefail - Use pipefail to catch pipeline errorserr-check-commands - Check command success explicitlyerr-shellcheck - Use ShellCheck for static analysiserr-debug-tracing - Use debug tracing with set -x and PS4var-use-arrays - Use arrays for lists instead of stringsvar-local-scope - Use local for function variablesvar-naming-conventions - Follow variable naming conventionsvar-readonly-constants - Use readonly for constantsvar-default-values - Use parameter expansion for defaultsquote-always-quote-variables - Always quote variable expansionsquote-dollar-at - Use "$@" for argument passingquote-command-substitution - Quote command substitutionsquote-brace-expansion - Use braces for variable clarityquote-here-documents - Use here documents for multi-line stringsquote-glob-safety - Control glob expansion explicitlyfunc-main-pattern - Use main() function patternfunc-single-purpose - Write single-purpose functionsfunc-return-values - Use return values correctlyfunc-documentation - Document functions with header commentsfunc-avoid-aliases - Prefer functions over aliasestest-double-brackets - Use [[ ]] for tests in bashtest-arithmetic - Use (( )) for arithmetic comparisonstest-explicit-empty - Use explicit empty/non-empty string teststest-file-operators - Use correct file test operatorstest-case-patterns - Use case for pattern matchingperf-builtins-over-external - Use builtins over external commandsperf-avoid-subshells - Avoid unnecessary subshellsperf-process-substitution - Use process substitution for temp filesperf-read-files - Read files efficientlyperf-parameter-expansion - Use parameter expansion for string operationsperf-batch-operations - Batch operations instead of loopsstyle-indentation - Use consistent indentationstyle-file-structure - Follow consistent file structurestyle-comments - Write useful commentsRead individual reference files for detailed explanations and code examples:
| File | Description |
|---|---|
| AGENTS.md | Complete compiled guide with all rules |
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and reference information |