Shell Scripts (Bash/POSIX)
Version 1.1.0
Community
January 2026
Note: This document is mainly for agents and LLMs to follow when maintaining, generating, or refactoring Shell Scripts (Bash/POSIX) codebases. Humans may also find it useful, but guidance here is optimized for automation and consistency by AI-assisted workflows.
Abstract
Comprehensive best practices guide for shell scripting (bash and POSIX sh), designed for AI agents and LLMs. Contains 48 rules across 9 categories, prioritized by impact from critical (safety & security, portability) to incremental (style & formatting). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
Table of Contents
- Safety & Security — CRITICAL
- 1.1 Avoid eval for Dynamic Commands — CRITICAL (eliminates code injection vector)
- 1.2 Create Secure Temporary Files — CRITICAL (prevents symlink attacks and race conditions)
- 1.3 Never Use SUID/SGID on Shell Scripts — CRITICAL (prevents privilege escalation vulnerabilities)
- 1.4 Prevent Argument Injection with Double Dash — CRITICAL (prevents options interpreted as filenames)
- 1.5 Prevent Command Injection from User Input — CRITICAL (prevents arbitrary code execution)
- 1.6 Use Absolute Paths for External Commands — CRITICAL (prevents PATH hijacking attacks)
- Portability — CRITICAL
- 2.1 Avoid Bashisms in POSIX Scripts — CRITICAL (prevents failures on dash/ash/busybox systems)
- 2.2 Choose Shebang Based on Portability Needs — CRITICAL (determines script compatibility across systems)
- 2.3 Use Portable Export Syntax — CRITICAL (prevents failures on strict POSIX shells)
- 2.4 Use Portable Test Constructs — CRITICAL (prevents silent logic failures across shells)
- 2.5 Use printf Instead of echo for Portability — CRITICAL (ensures consistent output across all systems)
- Error Handling — HIGH
- 3.1 Check Command Success Explicitly — HIGH (prevents cascading failures from silent errors)
- 3.2 Send Error Messages to stderr — HIGH (enables proper output piping and filtering)
- 3.3 Use Meaningful Exit Codes — HIGH (enables proper error handling by callers)
- 3.4 Use pipefail to Catch Pipeline Errors — HIGH (detects failures hidden in pipeline stages)
- 3.5 Use Strict Mode for Error Detection — HIGH (catches 90% of common script failures)
- 3.6 Use trap for Cleanup on Exit — HIGH (prevents resource leaks and orphaned processes)
- Variables & Data — HIGH
- 4.1 Follow Variable Naming Conventions — HIGH (prevents collisions with environment and builtins)
- 4.2 Use Arrays for Lists Instead of Strings — HIGH (prevents word splitting bugs in argument handling)
- 4.3 Use local for Function Variables — HIGH (prevents namespace pollution and hidden bugs)
- 4.4 Use Parameter Expansion for Defaults — HIGH (handles unset variables safely without conditionals)
- 4.5 Use readonly for Constants — HIGH (prevents accidental modification of configuration values)
- Quoting & Expansion — MEDIUM-HIGH
- 5.1 Always Quote Variable Expansions — MEDIUM-HIGH (prevents word splitting and glob expansion bugs)
- 5.2 Control Glob Expansion Explicitly — MEDIUM-HIGH (prevents unintended file matching in commands)
- 5.3 Quote Command Substitutions — MEDIUM-HIGH (prevents word splitting of command output)
- 5.4 Use "$@" for Argument Passing — MEDIUM-HIGH (preserves arguments with spaces correctly)
- 5.5 Use Braces for Variable Clarity — MEDIUM-HIGH (prevents ambiguous variable boundaries)
- 5.6 Use Here Documents for Multi-line Strings — MEDIUM-HIGH (avoids quoting complexity in long strings)
- Functions & Structure — MEDIUM
- 6.1 Document Functions with Header Comments — MEDIUM (enables maintenance and API understanding)
- 6.2 Prefer Functions Over Aliases — MEDIUM (enables arguments and proper scoping)
- 6.3 Use main() Function Pattern — MEDIUM (enables testing and prevents execution on source)
- 6.4 Use Return Values Correctly — MEDIUM (enables proper error propagation and testing)
- 6.5 Write Single-Purpose Functions — MEDIUM (improves testability and reusability)
- Testing & Conditionals — MEDIUM
- 7.1 Use (( )) for Arithmetic Comparisons — MEDIUM (provides clearer syntax and prevents string comparison bugs)
- 7.2 Use [[ ]] for Tests in Bash — MEDIUM (prevents word splitting and enables regex)
- 7.3 Use case for Pattern Matching — MEDIUM (cleaner than chained if/elif for multiple patterns)
- 7.4 Use Correct File Test Operators — MEDIUM (prevents logic errors with symlinks and special files)
- 7.5 Use Explicit Empty/Non-empty String Tests — MEDIUM (prevents misreads and silent failures)
- Performance — LOW-MEDIUM
- 8.1 Avoid Unnecessary Subshells — LOW-MEDIUM (reduces fork overhead and variable scope issues)
- 8.2 Batch Operations Instead of Loops — LOW-MEDIUM (single command vs N process spawns)
- 8.3 Read Files Efficiently — LOW-MEDIUM (prevents O(n) line reads and subshell overhead)
- 8.4 Use Builtins Over External Commands — LOW-MEDIUM (10-100× faster by avoiding fork/exec overhead)
- 8.5 Use Parameter Expansion for String Operations — LOW-MEDIUM (avoids external commands for common transformations)
- 8.6 Use Process Substitution for Temp Files — LOW-MEDIUM (eliminates file I/O and cleanup overhead)
- Style & Formatting — LOW
- 9.1 Follow Consistent File Structure — LOW (enables quick navigation and maintenance)
- 9.2 Use Consistent Indentation — LOW (improves readability and maintenance)
- 9.3 Use ShellCheck for Static Analysis — LOW (catches bugs before runtime)
- 9.4 Write Useful Comments — LOW (explains why, not what)
References
- https://google.github.io/styleguide/shellguide.html
- https://www.shellcheck.net/
- https://mywiki.wooledge.org/
- https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
- http://www.etalabs.net/sh_tricks.html
- https://developer.apple.com/library/archive/documentation/OpenSource/Conceptual/ShellScripting/ShellScriptSecurity/ShellScriptSecurity.html
Source Files
This document was compiled from individual reference files. For detailed editing or extension:
| File | Description |
|---|---|
| references/_sections.md | Category definitions and impact ordering |
| assets/templates/_template.md | Template for creating new rules |
| SKILL.md | Quick reference entry point |
| metadata.json | Version and reference URLs |