{"id":"465bdd29-8c50-44e5-bf73-c47e63364c24","shortId":"nJakpK","kind":"skill","title":"bash","tagline":"Auto-activate for .sh files, #!/bin/bash, #!/usr/bin/env bash. Bash scripting expertise following Google Shell Style Guide. Produces shell scripts following Google Shell Style Guide with proper error handling, quoting, and safety patterns. Use when: writing shell scripts, automat","description":"# Bash Scripting\n\n## Overview\n\nBash 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.\n\n## Quick Reference\n\n### Safety Header (always include)\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nIFS=$'\\n\\t'\n```\n\n| Flag | Effect |\n|------|--------|\n| `set -e` | Exit immediately on non-zero return |\n| `set -u` | Error on unset variables |\n| `set -o pipefail` | Pipe returns rightmost non-zero exit code |\n| `IFS=$'\\n\\t'` | Safer word splitting (no space splitting) |\n\n### Style Essentials\n\n| Rule | Good | Bad |\n|------|------|-----|\n| Function declaration | `my_func() { ... }` | `function my_func { ... }` |\n| Local variables | `local file_path=\"$1\"` | `file_path=$1` |\n| Constants | `readonly MAX_RETRIES=3` | `MAX_RETRIES=3` |\n| Variable expansion | `\"${var}\"` | `$var` |\n| Command substitution | `\"$(command)\"` | `` `command` `` |\n| Declare + assign | `local out; out=\"$(cmd)\"` | `local out=\"$(cmd)\"` |\n| File test | `[[ -f \"${file}\" ]]` | `[ -f $file ]` |\n\n### Common ShellCheck Fixes\n\n| Code | Issue | Fix |\n|------|-------|-----|\n| SC2086 | Unquoted variable | Double-quote: `\"${var}\"` |\n| SC2046 | Unquoted command sub | Quote or use `mapfile` |\n| SC2155 | Declare and assign together | Separate into two statements |\n| SC2034 | Unused variable | Add `export` or `# shellcheck disable=SC2034` |\n\n<workflow>\n\n## Workflow\n\n### Step 1: Start with the Safety Header\n\nEvery script begins with the shebang, strict mode, and a usage comment block describing purpose, usage, and examples.\n\n### Step 2: Define Functions\n\nOrganize logic into functions. Use `local` for all function-scoped variables. Use `main()` as the entry point, called at the bottom with `main \"$@\"`.\n\n### Step 3: Handle Arguments\n\nUse `getopts` for simple flags, or manual `while [[ $# -gt 0 ]]` parsing for long options. Always validate required arguments and print usage on error.\n\n### Step 4: Add Cleanup Traps\n\nUse `trap cleanup EXIT` for any script that creates temporary files, acquires locks, or needs to restore state on failure.\n\n### Step 5: Run ShellCheck\n\nValidate the script with `shellcheck script.sh` before committing. Fix all warnings; disable specific rules only with a justifying comment.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Always quote variables** — unquoted variables cause word splitting and glob expansion bugs; use `\"${var}\"` everywhere\n- **Always use ShellCheck** — run `shellcheck` on every script; it catches the majority of common bash pitfalls\n- **Prefer functions over inline code** — functions with `local` variables prevent accidental global state leaks\n- **Never use `eval`** unless absolutely necessary — it is the most common source of injection vulnerabilities in shell scripts\n- **Use `[[ ]]` not `[ ]`** — double brackets prevent word splitting and support regex matching\n- **Use `mktemp` for temporary files** — never hardcode `/tmp/myscript.tmp`; it creates race conditions\n- **Avoid parsing `ls` output** — use globs (`*.txt`) or `find` with `-print0` and `read -d ''` for safe file iteration\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering a script, verify:\n\n- [ ] Script starts with `#!/usr/bin/env bash` and `set -euo pipefail`\n- [ ] All variables are quoted with `\"${var}\"`\n- [ ] All function variables use `local`\n- [ ] `trap cleanup EXIT` is set if the script creates temporary resources\n- [ ] ShellCheck passes with no unacknowledged warnings\n- [ ] Script has a usage/help function accessible via `-h` or `--help`\n\n</validation>\n\n<example>\n\n## Example\n\nA safe script template with error handling, argument parsing, and cleanup:\n\n```bash\n#!/usr/bin/env bash\n#\n# Deploy an application to the target environment.\n#\n# Usage:\n#   deploy.sh [-v] [-e environment] <app_name>\n#\nset -euo pipefail\nIFS=$'\\n\\t'\n\nreadonly SCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nreadonly TMPDIR=\"$(mktemp -d)\"\n\ncleanup() {\n    rm -rf \"${TMPDIR}\"\n}\ntrap cleanup EXIT\n\nusage() {\n    cat <<EOF\nUsage: $(basename \"$0\") [-v] [-e environment] <app_name>\n\nOptions:\n  -v              Verbose output\n  -e ENVIRONMENT  Target environment (default: staging)\n  -h              Show this help\nEOF\n}\n\nmain() {\n    local verbose=false\n    local environment=\"staging\"\n\n    while getopts \":ve:h\" opt; do\n        case \"${opt}\" in\n            v) verbose=true ;;\n            e) environment=\"${OPTARG}\" ;;\n            h) usage; exit 0 ;;\n            :) echo \"Error: -${OPTARG} requires an argument\" >&2; exit 1 ;;\n            ?) echo \"Error: Unknown option -${OPTARG}\" >&2; exit 1 ;;\n        esac\n    done\n    shift $((OPTIND - 1))\n\n    if [[ $# -eq 0 ]]; then\n        echo \"Error: app_name is required\" >&2\n        usage >&2\n        exit 1\n    fi\n\n    local app_name=\"$1\"\n\n    if [[ \"${verbose}\" == true ]]; then\n        echo \"Deploying ${app_name} to ${environment}...\"\n    fi\n\n    # Build and deploy logic here\n    echo \"Deployed ${app_name} to ${environment} successfully.\"\n}\n\nmain \"$@\"\n```\n\n</example>\n\n---\n\n## References Index\n\nFor detailed guides and code examples, refer to the following documents in `references/`:\n\n- **[Style Guide](references/style.md)**\n  - Google Shell Style Guide patterns: file headers, function naming, variable naming, quoting rules, error handling.\n- **[Common Patterns](references/patterns.md)**\n  - Argument parsing (getopts), trap for cleanup, here-docs, process substitution, array manipulation, associative arrays.\n- **[Safety & Defensive Scripting](references/safety.md)**\n  - Shellcheck compliance, avoiding common pitfalls, handling spaces in filenames, proper exit codes, signal handling.\n\n---\n\n## Official References\n\n- <https://google.github.io/styleguide/shellguide.html>\n- <https://www.gnu.org/software/bash/manual/>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n- [Bash](https://github.com/cofin/flow/blob/main/templates/styleguides/languages/bash.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["bash","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-bash","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/bash","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (6,239 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T01:03:25.145Z","embedding":null,"createdAt":"2026-04-23T13:03:57.779Z","updatedAt":"2026-04-24T01:03:25.145Z","lastSeenAt":"2026-04-24T01:03:25.145Z","tsv":"'/bin/bash':8 '/cofin/flow/blob/main/templates/styleguides/general.md)':769 '/cofin/flow/blob/main/templates/styleguides/languages/bash.md)':773 '/software/bash/manual/':748 '/styleguide/shellguide.html':745 '/tmp/myscript.tmp':426 '/usr/bin/env':9,79,459,516 '0':282,543,561,605,630 '1':141,144,217,614,622,627,642,647 '2':242,612,620,638,640 '3':149,152,270 '4':297 '5':322 'absolut':394 'access':498 'accident':386 'acquir':312 'activ':4 'add':209,298 'alway':76,287,345,360 'app':634,645,654,666 'applic':520 'argument':272,290,511,611,708 'array':719,722 'assign':162,200 'associ':721 'auto':3 'auto-activ':2 'automat':40 'avoid':431,729 'bad':128 'baselin':751 'basenam':560 'bash':1,10,11,41,44,78,80,374,460,515,517,541,770 'begin':225 'block':235 'bottom':266 'bracket':411 'bug':356 'build':659 'call':263 'case':593,784 'cat':557 'catch':369 'caus':350 'cd':539 'checkpoint':450 'cleanup':299,303,477,514,549,554,713 'cmd':166,169 'code':114,179,380,678,738 'command':157,159,160,191 'comment':234,343 'commit':332 'common':176,373,400,705,730 'complianc':728 'condit':430 'constant':145 'cover':55 'creat':309,428,484 'd':444,548 'declar':130,161,198 'default':47,573 'defens':724 'defin':243 'deliv':452 'deploy':518,653,661,665 'deploy.sh':526 'describ':236 'detail':675,787 'dir':538 'dirnam':540 'disabl':213,336 'distribut':52 'doc':716 'document':684 'done':624 'doubl':186,410 'double-quot':185 'duplic':761 'e':90,528,563,569,599 'echo':606,615,632,652,664 'edg':783 'effect':88 'emphasi':66 'entri':261 'environ':524,529,564,570,572,585,600,657,669 'eof':558,579 'eq':629 'error':29,100,295,509,607,616,633,703 'esac':623 'essenti':125 'euo':82,463,531 'eval':392 'everi':223,366 'everywher':359 'exampl':240,503,679 'exit':91,113,304,478,555,604,613,621,641,737 'expans':154,355 'expertis':13 'export':210 'f':172,174 'failur':320 'fals':583 'fi':643,658 'file':7,139,142,170,173,175,311,423,447,695 'filenam':735 'find':439 'fix':178,181,333 'flag':87,277 'focus':777 'follow':14,22,59,683 'func':132,135 'function':129,133,244,248,254,377,381,472,497,697 'function-scop':253 'general':765 'generic':756 'getopt':274,588,710 'github.com':768,772 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':767 'github.com/cofin/flow/blob/main/templates/styleguides/languages/bash.md)':771 'glob':354,436 'global':387 'good':127 'googl':15,23,61,690 'google.github.io':744 'google.github.io/styleguide/shellguide.html':743 'gt':281 'guardrail':344 'guid':18,26,64,676,688,693 'h':500,575,590,602 'handl':30,271,510,704,732,740 'hardcod':425 'header':75,222,696 'help':502,578 'here-doc':714 'idiomat':56 'if':84,115,533 'immedi':92 'includ':77 'index':673 'inject':403 'inlin':379 'integr':786 'issu':180 'iter':448 'justifi':342 'keep':774 'language/framework':757 'leak':389 'linux':51 'local':136,138,163,167,250,383,475,581,584,644 'lock':313 'logic':246,662 'long':285 'ls':433 'main':258,268,580,671 'maintain':71 'major':371 'manipul':720 'manual':279 'mapfil':196 'match':418 'max':147,150 'mktemp':420,547 'mode':230 'n':85,116,534 'name':635,646,655,667,698,700 'necessari':395 'need':315 'never':390,424 'non':95,111 'non-zero':94,110 'o':105 'offici':741 'opt':591,594 'optarg':601,608,619 'optind':626 'option':286,565,618 'organ':245 'output':434,568 'overview':43 'pars':283,432,512,709 'pass':488 'path':140,143 'pattern':34,58,694,706 'pipe':107 'pipefail':83,106,464,532 'pitfal':375,731 'point':262 'prefer':376 'prevent':385,412 'principl':766 'print':292 'print0':441 'process':717 'produc':19 'proper':28,736 'purpos':237 'pwd':544 'quick':72 'quot':31,187,193,346,468,701 'race':429 'read':443 'readabl':69 'readon':146,536,545 'reduc':760 'refer':73,672,680,686,742 'references/patterns.md':707 'references/safety.md':726 'references/style.md':689 'regex':417 'requir':289,609,637 'resourc':486 'restor':317 'retri':148,151 'return':97,108 'rf':551 'rightmost':109 'rm':550 'rule':126,338,702,758 'run':323,363 'safe':446,505 'safer':118 'safeti':33,68,74,221,723 'sc2034':206,214 'sc2046':189 'sc2086':182 'sc2155':197 'scope':255 'script':12,21,39,42,57,224,307,327,367,407,454,456,483,493,506,537,725 'script.sh':330 'separ':202 'set':81,89,98,104,462,480,530 'sh':6 'share':749,753 'shebang':228 'shell':16,20,24,38,48,62,406,691 'shellcheck':177,212,324,329,362,364,487,727 'shift':625 'show':576 'signal':739 'simpl':276 'skill':54,764,776 'skill-bash' 'sourc':401,542 'source-cofin' 'space':122,733 'specif':337,781 'split':120,123,352,414 'stage':574,586 'start':218,457 'state':318,388 'statement':205 'step':216,241,269,296,321 'strict':229 'style':17,25,63,124,687,692 'styleguid':750,754 'sub':192 'substitut':158,718 'success':670 'support':416 'target':523,571 'templat':507 'temporari':310,422,485 'test':171 'tmpdir':546,552 'togeth':201 'tool':780 'tool-specif':779 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'trap':300,302,476,553,711 'true':598,650 'two':204 'txt':437 'u':99 'unacknowledg':491 'unknown':617 'unless':393 'unquot':183,190,348 'unset':102 'unus':207 'usag':233,238,293,525,556,559,603,639 'usage/help':496 'use':35,195,249,257,273,301,357,361,391,408,419,435,474,752 'v':527,562,566,596 'valid':288,325,449 'var':155,156,188,358,470 'variabl':103,137,153,184,208,256,347,349,384,466,473,699 've':589 'verbos':567,582,597,649 'verifi':455 'via':499 'vulner':404 'warn':335,492 'word':119,351,413 'workflow':215,782 'write':37 'www.gnu.org':747 'www.gnu.org/software/bash/manual/':746 'zero':96,112","prices":[{"id":"6458c779-853d-48cb-8e39-91a49ae35e9f","listingId":"465bdd29-8c50-44e5-bf73-c47e63364c24","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:03:57.779Z"}],"sources":[{"listingId":"465bdd29-8c50-44e5-bf73-c47e63364c24","source":"github","sourceId":"cofin/flow/bash","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/bash","isPrimary":false,"firstSeenAt":"2026-04-23T13:03:57.779Z","lastSeenAt":"2026-04-24T01:03:25.145Z"}],"details":{"listingId":"465bdd29-8c50-44e5-bf73-c47e63364c24","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"bash","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"16865abd3649cdbeab80ebd011cca3e93f2a3dfd","skill_md_path":"skills/bash/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/bash"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"bash","description":"Auto-activate for .sh files, #!/bin/bash, #!/usr/bin/env bash. Bash scripting expertise following Google Shell Style Guide. Produces shell scripts following Google Shell Style Guide with proper error handling, quoting, and safety patterns. Use when: writing shell scripts, automating tasks, processing text, or creating CLI tools. Covers error handling, variable quoting, function patterns, and portable scripting. Not for Python/Ruby scripts that happen to call shell commands."},"skills_sh_url":"https://skills.sh/cofin/flow/bash"},"updatedAt":"2026-04-24T01:03:25.145Z"}}