agentleFS
n-n-coden-n-code/n-n-code-skills/.agents/skills/coding-guidance-bash/SKILL.md

coding-guidance-bash

Skill4 starsChanged 11 days agoMITView on GitHub

Bash implementation and review guidance for automation and repository scripts; not for one-off command execution, POSIX `sh`, or release-workflow design where `project-release-maintainer` is primary. Covers safe quoting, explicit failure handling, process ownership, and maintainable shell boundaries.

The file

Show its rules and text

We split this skill into the rules it gives an agent

37 rules. About 0 are common, 26 are distinctive, and 11 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈26

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read the touched scripts, entrypoints, call sites, and nearby docs before editing.

    line 47
  2. Distinctive:

    Keep the contract narrow: inputs, outputs, exit codes, environment dependencies, filesystem effects, and external tool requirements should …

    line 52
  3. Distinctive:

    Add or update shell tests when the repo has them.

    line 58
  4. Distinctive:

    Run the narrowest relevant formatter, linter, and script tests the repo supports.

    line 60
  5. Distinctive:

    Use this instead of the default implementation workflow when the task is primarily cleanup or restructuring:

    line 65
  6. Distinctive:

    Keep tests or runnable validation passing after each slice.

    line 73
  7. Distinctive:

    Stop when the script is easier to read, safer to invoke, and easier to debug.

    line 75
  8. Distinctive:

    When reviewing (not implementing), skip the implementation workflow and use this instead:

    line 80
  9. Distinctive:

    Read the change in full before commenting.

    line 83
  10. Distinctive:

    Do not edit scripts or require findings to be fixed unless the user also asks for remediation.

    line 92
  11. Very specific:

    Start executable Bash scripts with #!/usr/bin/env bash unless the repo has a stricter shebang convention

    line 99
  12. Very specific:

    Follow the repo's failure-handling convention.

    line 101
  13. Very specific:

    Use explicit status checks where errexit semantics are ambiguous or failure recovery is part of the contract

    line 104
  14. Distinctive:

    Use arrays for argument vectors.

    line 107
  15. Distinctive:

    Check exit statuses deliberately.

    line 111
  16. Very specific:

    Treat $IFS, globs, current working directory, and environment variables as boundary conditions, not stable ambient assumptions

    line 115
  17. Distinctive:

    Prefer functions for meaningful units of behavior.

    line 120
  18. Very specific:

    Use local inside functions unless a variable is intentionally shared

    line 122
  19. Very specific:

    Prefer [[ ... ]] for Bash conditionals and case for multi-branch string matching

    line 123
  20. Very specific:

    Prefer printf over echo when escaping, flags, or portability ambiguity matter

    line 125
  21. Very specific:

    Use command substitution $() instead of backticks

    line 127
  22. Distinctive:

    Avoid silent fallbacks on missing tools or files unless the script is explicitly best-effort

    line 141
  23. Distinctive:

    Use stable exit-code meanings when the script is likely to be called by other automation

    line 143
  24. Distinctive:

    Prefer long, readable option names for user-facing interfaces when the repo does not already prescribe a short-only style

    line 148
  25. Distinctive:

    Keep functions small enough to understand locally.

    line 150
  26. Very specific:

    Run shellcheck and shfmt where the repo uses them

    line 152
  27. Distinctive:

    Prefer Bats or the repo's existing shell-test framework for non-trivial scripts

    line 153
  28. Distinctive:

    Document required tools and minimum Bash features when the script depends on them

    line 155
  29. Distinctive:

    Use these when the right choice is not obvious:

    line 160
  30. Distinctive:

    Language fit: if the task needs nested data structures, complex parsing, or large in-memory transforms, shell may be the wrong tool.

    line 162
  31. Distinctive:

    Quoting pressure: if command construction becomes hard to reason about, switch to arrays or redesign the interface before adding more flags.

    line 164
  32. Very specific:

    Failure visibility: if set -e behavior is unclear in a construct, make the check explicit rather than assuming the shell will fail the …

    line 166
  33. Distinctive:

    Process ownership: if the script backgrounds work, define who waits, cleans up, and reports failures before adding more parallelism.

    line 168
  34. Distinctive:

    Portability pressure: if a script relies on GNU-only flags, a Bash 5.x feature, or OS-specific tools, document and validate that boundary …

    line 170
  35. Distinctive:

    Repo conventions: if the repo has established patterns for shebangs, strict mode, shellcheck, shfmt, or helper libraries, follow them …

    line 173
  36. Distinctive:

    Adjacent issues: do not modify unrelated issues unless they are required for the requested change's correctness or safety.

    line 180
  37. Very specific:

    External-tool boundary: if a script depends on jq, awk, sed, or platform-specific tooling, treat that dependency as part of the user-facing …

    line 185

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Bash Coding Guidance

This skill adds portable Bash implementation, refactoring, and review guidance.

Adjacent Skills

This skill provides portable Bash engineering principles. Compose with:

  • Workflow: thinking (ambiguous decision framing), recursive-thinking (stress-testing), security (threat modeling)
  • Domain overlays: project-core-dev (repo-specific completion discovery and reporting when needed), project-platform-diagnose (environment-sensitive diagnosis), project-release-maintainer (release or packaging workflows that happen to use Bash)

Reference Map

Load references only when the task needs that depth:

  • references/failure-and-cleanup.md for strict options, errexit edge cases, traps, temporary resources, and explicit failure propagation
  • references/process-and-filesystem-safety.md for command construction, background process ownership, concurrent invocation, filename-safe iteration, and cross-platform tool boundaries

When Not to Lean on This Skill

  • non-shell work
  • POSIX sh portability work where Bash-only features are not allowed (adapt the guidance to the repo's POSIX-shell contract instead of importing Bash-only defaults)
  • large data processing jobs that should realistically move to Python, awk, or another language with stronger structure
  • broader release, packaging, or publishing workflow design that only happens to call Bash; use project-release-maintainer first

Implementation Workflow

  1. Read the touched scripts, entrypoints, call sites, and nearby docs before editing.
  2. Infer the intended contract from current usage text, flags, tests, and environment assumptions. Ask only when multiple plausible script behaviors would change semantics.
  3. Keep the contract narrow: inputs, outputs, exit codes, environment dependencies, filesystem effects, and external tool requirements should be explicit.
  4. Implement with deliberate failure handling, safe quoting, arrays for argv construction, functions for meaningful substeps, and cleanup traps for temporary state.
  5. Add or update shell tests when the repo has them; otherwise add the smallest reproducible validation path you can run directly.
  6. Run the narrowest relevant formatter, linter, and script tests the repo supports.

Refactoring Workflow

Use this instead of the default implementation workflow when the task is primarily cleanup or restructuring:

  1. Capture current behavior, flags, environment assumptions, platform dependencies, and failure modes.
  2. Break the refactor into small slices that preserve behavior.
  3. Replace copy-pasted command assembly, hidden globals, unsafe loops, and tangled control flow one step at a time.
  4. Keep tests or runnable validation passing after each slice; add characterization coverage first when behavior is unclear.
  5. Stop when the script is easier to read, safer to invoke, and easier to debug.

Review Workflow

When reviewing (not implementing), skip the implementation workflow and use this instead:

  1. Read the change in full before commenting.
  2. Identify findings, ordered by severity: Critical > Important > Suggestion.
  3. Prioritize quoting and word-splitting bugs, globbing hazards, accidental masking of failing commands, trap and cleanup bugs, unsafe temp-file handling, destructive command risks, portability mismatches, environment assumptions, and missing tests.
  4. State findings with concrete evidence and the likely consequence.

Do not edit scripts or require findings to be fixed unless the user also asks for remediation.

Bash Rules

First tier - causes bugs

  • Start executable Bash scripts with #!/usr/bin/env bash unless the repo has a stricter shebang convention
  • Follow the repo's failure-handling convention. Enable -u, pipefail, -e, and -E only after checking how optional values, conditionals, functions, pipelines, subshells, and command substitutions are expected to behave
  • Use explicit status checks where errexit semantics are ambiguous or failure recovery is part of the contract
  • Quote expansions by default: "$var", "${arr[@]}", and "$(cmd)"
  • Use arrays for argument vectors; do not build command lines with string concatenation
  • Distinguish stdout data from stderr diagnostics so callers can compose the script safely
  • Check exit statuses deliberately; do not rely on pipelines, subshells, or command substitutions without understanding how failures propagate
  • Clean up temp files and directories with trap when the script allocates them
  • Treat $IFS, globs, current working directory, and environment variables as boundary conditions, not stable ambient assumptions

Second tier - prevents mistakes

  • Prefer functions for meaningful units of behavior; keep top-level script flow readable
  • Use local inside functions unless a variable is intentionally shared
  • Prefer [[ ... ]] for Bash conditionals and case for multi-branch string matching
  • Prefer printf over echo when escaping, flags, or portability ambiguity matter
  • Use command substitution $() instead of backticks
  • Name flags, env vars, and functions for what they do; shell scripts become unreadable quickly when names get vague
  • Introduce no new ShellCheck findings and explain any necessary scoped suppression; distinguish existing unrelated debt from regressions

Input, output, and contract design

  • Provide --help or usage text for non-trivial scripts
  • Make required env vars, positional args, flags, and side effects explicit near the top of the file
  • Exit with non-zero status on real failure and reserve zero for success
  • Print machine-consumable output in a stable format when other tools are meant to parse it
  • Avoid silent fallbacks on missing tools or files unless the script is explicitly best-effort
  • Use stable exit-code meanings when the script is likely to be called by other automation

Style, testing, and tooling

  • Prefer long, readable option names for user-facing interfaces when the repo does not already prescribe a short-only style
  • Keep functions small enough to understand locally; split when one function starts owning parsing, validation, execution, and reporting all at once
  • Run shellcheck and shfmt where the repo uses them
  • Prefer Bats or the repo's existing shell-test framework for non-trivial scripts
  • Document required tools and minimum Bash features when the script depends on them

Decision Heuristics

Use these when the right choice is not obvious:

  • Language fit: if the task needs nested data structures, complex parsing, or large in-memory transforms, shell may be the wrong tool.
  • Quoting pressure: if command construction becomes hard to reason about, switch to arrays or redesign the interface before adding more flags.
  • Failure visibility: if set -e behavior is unclear in a construct, make the check explicit rather than assuming the shell will fail the right way.
  • Process ownership: if the script backgrounds work, define who waits, cleans up, and reports failures before adding more parallelism.
  • Portability pressure: if a script relies on GNU-only flags, a Bash 5.x feature, or OS-specific tools, document and validate that boundary instead of hiding it.
  • Repo conventions: if the repo has established patterns for shebangs, strict mode, shellcheck, shfmt, or helper libraries, follow them unless they create a correctness or safety problem.
  • Narrowness vs. quality: implement the narrowest change that solves the problem. When narrowness conflicts with correctness or safety, prefer correctness. When it conflicts with style alone, prefer narrowness unless the task is explicitly a cleanup.
  • Adjacent issues: do not modify unrelated issues unless they are required for the requested change's correctness or safety; report them separately.
  • Abstraction threshold: three similar command sequences or repeated flag parsing pain is a pattern; before extracting, check whether a function, a helper script, or a small move to another language is the simpler move.
  • External-tool boundary: if a script depends on jq, awk, sed, or platform-specific tooling, treat that dependency as part of the user-facing contract.

Validation

For implementation, a change is done when:

  • shellcheck or the repo's equivalent linter reports no new findings
  • shell formatting is run when the repo has a formatter
  • changed --help, argument parsing, or top-level script startup paths are smoke-tested before deeper functional validation
  • existing shell tests pass
  • new or changed behavior has test coverage, or the lack of coverage is called out with a concrete reason
  • non-trivial scripts have a direct smoke path such as --help or a minimal fixture invocation
  • destructive or environment-mutating paths were verified against a safe test fixture rather than assumed correct
  • portability-sensitive changes were tested on the affected platform or the remaining platform risk was called out explicitly

For review, completion means Critical and Important findings are reported with concrete evidence, likely consequence, and any validation gap. Unfixed findings do not make the review incomplete.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.