skills/bash/SKILL.md
Use when editing shell scripts, .sh files, bash shebangs, CLI automation, text processing pipelines, shell error handling, quoting, traps, functions, or portable Bash patterns.
npx skillsauth add cofin/flow bashInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Bash is the default shell on most Linux distributions. This skill covers idiomatic scripting patterns following the Google Shell Style Guide, with emphasis on safety, readability, and maintainability.
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
| Flag | Effect |
|------|--------|
| set -e | Exit immediately on non-zero return |
| set -u | Error on unset variables |
| set -o pipefail | Pipe returns rightmost non-zero exit code |
| IFS=$'\n\t' | Safer word splitting (no space splitting) |
| Rule | Good | Bad |
|------|------|-----|
| Function declaration | my_func() { ... } | function my_func { ... } |
| Local variables | local file_path="$1" | file_path=$1 |
| Constants | readonly MAX_RETRIES=3 | MAX_RETRIES=3 |
| Variable expansion | "${var}" | $var |
| Command substitution | "$(command)" | `command` |
| Declare + assign | local out; out="$(cmd)" | local out="$(cmd)" |
| File test | [[ -f "${file}" ]] | [ -f $file ] |
| Code | Issue | Fix |
|------|-------|-----|
| SC2086 | Unquoted variable | Double-quote: "${var}" |
| SC2046 | Unquoted command sub | Quote or use mapfile |
| SC2155 | Declare and assign together | Separate into two statements |
| SC2034 | Unused variable | Add export or # shellcheck disable=SC2034 |
Every script begins with the shebang, strict mode, and a usage comment block describing purpose, usage, and examples.
Organize logic into functions. Use local for all function-scoped variables. Use main() as the entry point, called at the bottom with main "$@".
Use getopts for simple flags, or manual while [[ $# -gt 0 ]] parsing for long options. Always validate required arguments and print usage on error.
Use trap cleanup EXIT for any script that creates temporary files, acquires locks, or needs to restore state on failure.
Validate the script with shellcheck script.sh before committing. Fix all warnings; disable specific rules only with a justifying comment.
"${var}" everywhereshellcheck on every script; it catches the majority of common bash pitfallslocal variables prevent accidental global state leakseval unless absolutely necessary — it is the most common source of injection vulnerabilities in shell scripts[[ ]] not [ ] — double brackets prevent word splitting and support regex matchingmktemp for temporary files — never hardcode /tmp/myscript.tmp; it creates race conditionsls output — use globs (*.txt) or find with -print0 and read -d '' for safe file iterationBefore delivering a script, verify:
#!/usr/bin/env bash and set -euo pipefail"${var}"localtrap cleanup EXIT is set if the script creates temporary resources-h or --helpA safe script template with error handling, argument parsing, and cleanup:
#!/usr/bin/env bash
#
# Deploy an application to the target environment.
#
# Usage:
# deploy.sh [-v] [-e environment] <app_name>
#
set -euo pipefail
IFS=$'\n\t'
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly TMPDIR="$(mktemp -d)"
cleanup() {
rm -rf "${TMPDIR}"
}
trap cleanup EXIT
usage() {
cat <<EOF
Usage: $(basename "$0") [-v] [-e environment] <app_name>
Options:
-v Verbose output
-e ENVIRONMENT Target environment (default: staging)
-h Show this help
EOF
}
main() {
local verbose=false
local environment="staging"
while getopts ":ve:h" opt; do
case "${opt}" in
v) verbose=true ;;
e) environment="${OPTARG}" ;;
h) usage; exit 0 ;;
:) echo "Error: -${OPTARG} requires an argument" >&2; exit 1 ;;
?) echo "Error: Unknown option -${OPTARG}" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
if [[ $# -eq 0 ]]; then
echo "Error: app_name is required" >&2
usage >&2
exit 1
fi
local app_name="$1"
if [[ "${verbose}" == true ]]; then
echo "Deploying ${app_name} to ${environment}..."
fi
# Build and deploy logic here
echo "Deployed ${app_name} to ${environment} successfully."
}
main "$@"
</example>
For detailed guides and code examples, refer to the following documents in references/:
testing
Use when syncing Beads state to markdown, checking Flow status, refreshing context docs, validating task markers, or reporting ready/blocked Flow work.
testing
Use when initializing Flow in a repo, configuring .agents, installing or checking Beads bd, setting local-only sync policy, or creating first project context files.
data-ai
Use when drafting PRDs, researching, planning, refining, revising, or creating .agents/specs/<flow_id>/spec.md worksheets for Flow.
testing
Use when implementing Flow tasks from Beads or spec.md, claiming ready work, applying TDD, recording task notes, committing, and syncing after task state changes.