bash-style
Bash scripting conventions based on the Google Shell Style Guide. Applied to all .sh files and bash scripts.
Write bash scripts that are safe, readable, and consistent.
Shell Options
Start every script with:
#!/usr/bin/env bash
set -euo pipefail
Formatting
-
Indent 2 spaces, no tabs.
-
Max 80 characters per line.
-
; thenand; doon the same line asif/for/while. -
Split pipelines one per line when they don't fit:
command1 \ | command2 \ | command3
Naming
- Functions and variables:
lower_snake_case - Constants and exports:
UPPER_SNAKE_CASE, declared withreadonlyordeclare -r - Source filenames: lowercase, underscores if needed
Variables
-
Quote all variables:
"${var}"not$var. -
Use
"${var}"with braces for all non-special variables. -
Use
localfor function variables. Separate declaration from command substitution assignment:local my_var my_var="$(some_command)"
Functions
-
Use
()syntax, braces on the same line:my_func() { … } -
Add a header comment for functions over 10 lines.
-
Put all functions near the top, after constants.
-
Scripts with functions must have a
mainfunction called at the bottom:main "$@"
Conditionals and Tests
- Use
[[ … ]]not[ … ]ortest. - Use
==for string equality, not=. - Use
(( … ))for arithmetic, notletorexpr. - Use
-z/-nfor empty/non-empty string tests.
Safety
- Always check return values. Use
if ! commandor check$?. - Use arrays for argument lists, not space-separated strings.
- Use
$(command)not backticks. - Use
./*not*for wildcard expansion. - Never use
eval. - Errors go to stderr:
echo "error" >&2
Comments
- Every file starts with a
#description after the shebang. - Use
# TODO(name):format for TODOs.
Scope
- Keep scripts under 100 lines. If longer, split into multiple scripts or rewrite in a structured language.
- Shell is for small utilities and wrappers, not complex logic.
RULE.md | | Raw
Bash Style
Write bash scripts that are safe, readable, and consistent.
Shell Options
Start every script with:
#!/usr/bin/env bash
set -euo pipefail
Formatting
-
Indent 2 spaces, no tabs.
-
Max 80 characters per line.
-
; thenand; doon the same line asif/for/while. -
Split pipelines one per line when they don't fit:
command1 \ | command2 \ | command3
Naming
- Functions and variables:
lower_snake_case - Constants and exports:
UPPER_SNAKE_CASE, declared withreadonlyordeclare -r - Source filenames: lowercase, underscores if needed
Variables
-
Quote all variables:
"${var}"not$var. -
Use
"${var}"with braces for all non-special variables. -
Use
localfor function variables. Separate declaration from command substitution assignment:local my_var my_var="$(some_command)"
Functions
-
Use
()syntax, braces on the same line:my_func() { … } -
Add a header comment for functions over 10 lines.
-
Put all functions near the top, after constants.
-
Scripts with functions must have a
mainfunction called at the bottom:main "$@"
Conditionals and Tests
- Use
[[ … ]]not[ … ]ortest. - Use
==for string equality, not=. - Use
(( … ))for arithmetic, notletorexpr. - Use
-z/-nfor empty/non-empty string tests.
Safety
- Always check return values. Use
if ! commandor check$?. - Use arrays for argument lists, not space-separated strings.
- Use
$(command)not backticks. - Use
./*not*for wildcard expansion. - Never use
eval. - Errors go to stderr:
echo "error" >&2
Comments
- Every file starts with a
#description after the shebang. - Use
# TODO(name):format for TODOs.
Scope
- Keep scripts under 100 lines. If longer, split into multiple scripts or rewrite in a structured language.
- Shell is for small utilities and wrappers, not complex logic.
1.0.0 — 2026-04-30
Added
- Initial rule based on Google Shell Style Guide
- Covers shell options, formatting, naming, variables, functions, conditionals, safety, comments, and scope
- Google Shell Style Guide — Primary source for all conventions in this rule (adopted in v1.0.0)
- ShellCheck — Recommended static analysis tool referenced by the guide (adopted in v1.0.0)