{"id":"8d1ea825-c6fd-42fc-9ed7-e8d44814fa76","shortId":"gjNVDT","kind":"skill","title":"linux-bash-scripting","tagline":">-","description":"# Linux Bash Scripting\n\nProduce bash scripts that pass `shellcheck --enable=all` and `shfmt -d` with zero warnings.\n\nTarget: GNU Bash 4.4+ on Linux. No macOS/BSD workarounds, no Windows paths, no POSIX-only restrictions.\n\n## Script Foundation\n\n```bash\n#!/usr/bin/env bash\nset -Eeuo pipefail\nshopt -s inherit_errexit\n\nreadonly SCRIPT_DIR=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]}\")\" && pwd -P)\"\n\ntrap 'printf \"Error at %s:%d\\n\" \"${BASH_SOURCE[0]}\" \"$LINENO\" >&2' ERR\ntrap 'rm -rf -- \"${_tmpdir:-}\"' EXIT\n```\n\n- `-E` propagates ERR traps into functions\n- `inherit_errexit` propagates errexit into `$()`  command substitutions\n- Always create temp dirs under the EXIT trap: `_tmpdir=$(mktemp -d)`\n- Wrap body in `main() { ... }` with source guard: `[[ \"${BASH_SOURCE[0]}\" == \"$0\" ]] && main \"$@\"` -- enables sourcing for testing\n\n## Core Rules\n\n- Quote every expansion: `\"$var\"`, `\"$(cmd)\"`, `\"${array[@]}\"`\n- `local` for function variables, `local -r` for function constants, `readonly` for script constants\n- `printf '%s\\n'` over `echo` -- predictable behavior, no flag interpretation\n- `[[ ]]` for conditionals; `(( ))` for arithmetic; `$()` over backticks\n- End options with `--`: `rm -rf -- \"$path\"`, `grep -- \"$pattern\" \"$file\"`\n- Require env vars: `: \"${VAR:?must be set}\"`\n- Never `eval` user input; build commands as arrays: `cmd=(\"grep\" \"--\" \"$pat\" \"$f\"); \"${cmd[@]}\"`\n- Separate `local` from assignment to preserve exit codes: `local val; val=$(cmd)`\n- Debug tracing: `PS4='+${BASH_SOURCE[0]}:${LINENO}: '` with `bash -x` -- shows file:line per command\n- Named exit codes: `readonly EX_USAGE=64 EX_CONFIG=78` -- no magic numbers in `exit`\n- Pipeline diagnostics: `\"${PIPESTATUS[@]}\"` shows exit code of each pipe stage, not just last failure\n\n## Safe Iteration\n\n```bash\n# NUL-delimited file processing\nwhile IFS= read -r -d '' f; do\n    process \"$f\"\ndone < <(find /path -type f -name '*.log' -print0)\n\n# Array from command output\nreadarray -t lines < <(command)\nreadarray -d '' files < <(find . -print0)\n\n# Glob with no-match guard\nfor f in *.txt; do [[ -e \"$f\" ]] || continue; process \"$f\"; done\n```\n\n## Argument Parsing\n\n```bash\nverbose=false; output=\"\"\nwhile [[ $# -gt 0 ]]; do\n    case \"$1\" in\n        -v|--verbose) verbose=true; shift ;;\n        -o|--output)  output=\"$2\"; shift 2 ;;\n        -h|--help)    usage; exit 0 ;;\n        --)           shift; break ;;\n        -*)           printf 'Unknown: %s\\n' \"$1\" >&2; exit 1 ;;\n        *)            break ;;\n    esac\ndone\n```\n\n## Production Patterns\n\n**Dependency check:**\n```bash\nrequire() { command -v \"$1\" &>/dev/null || { printf 'Missing: %s\\n' \"$1\" >&2; exit 1; }; }\nrequire jq; require curl\n```\n\n**Dry-run wrapper:**\n```bash\nrun() { if [[ \"${DRY_RUN:-}\" == \"1\" ]]; then printf '[dry] %s\\n' \"$*\" >&2; else \"$@\"; fi; }\nrun cp \"$src\" \"$dst\"\n```\n\n**Atomic file write** -- write to temp, rename into place:\n```bash\natomic_write() { local tmp; tmp=$(mktemp); cat >\"$tmp\"; mv -- \"$tmp\" \"$1\"; }\ngenerate_config | atomic_write /etc/app/config.yml\n```\n\n**Retry with backoff:**\n```bash\nretry() { local n=0 max=5 delay=1; until \"$@\"; do ((++n>=max)) && return 1; sleep $delay; ((delay*=2)); done; }\nretry curl -fsSL \"$url\"\n```\n\n**Script locking** -- prevent concurrent runs:\n```bash\nexec 9>/var/lock/\"${0##*/}\".lock\nflock -n 9 || { printf 'Already running\\n' >&2; exit 1; }\n```\n\n**Idempotent operations** -- safe to rerun:\n```bash\nensure_dir()  { [[ -d \"$1\" ]] || mkdir -p -- \"$1\"; }\nensure_link() { [[ -L \"$2\" ]] || ln -s -- \"$1\" \"$2\"; }\n```\n\n**Input validation:** `[[ \"$1\" =~ ^[1-9][0-9]*$ ]] || die \"Invalid: $1\"` -- validate at script boundaries with `[[ =~ ]]`\n\n- `umask 077` for scripts creating sensitive files\n- Signal cleanup: `trap 'cleanup; exit 130' INT TERM` -- preserves correct exit codes for callers\n\n## Logging\n\n```bash\nlog() { printf '[%s] [%s] %s\\n' \"$(date -Iseconds)\" \"$1\" \"${*:2}\" >&2; }\ninfo()  { log INFO \"$@\"; }\nwarn()  { log WARN \"$@\"; }\nerror() { log ERROR \"$@\"; }\ndie()   { error \"$@\"; exit 1; }\n```\n\n## Anti-Patterns\n\n| Bad | Fix |\n|-----|-----|\n| `for f in $(ls)` | `for f in *; do` or `find -print0 \\| while read` |\n| `local x=$(cmd)` | `local x; x=$(cmd)` -- preserves exit code |\n| `echo \"$data\"` | `printf '%s\\n' \"$data\"` |\n| `cat file \\| grep` | `grep pat file` |\n| `kill -9 $pid` first | `kill \"$pid\"` first, `-9` as last resort |\n| `cd dir; cmd` | `cd dir || exit 1` or subshell `(cd dir && cmd)` |\n\n## Performance\n\n- Parameter expansion over externals: `${path%/*}` not `dirname`, `${path##*/}` not `basename`, `${var//old/new}` not `sed`\n- `(( ))` over `expr`; `[[ =~ ]]` over `echo | grep`\n- Cache results: `val=$(cmd)` once, reuse `$val`\n- `xargs -0 -P \"$(nproc)\"` for parallel work\n- `declare -A map` for lookups instead of repeated grep\n\n## Bash 4.4+ / 5.x\n\n- `${var@Q}` shell-quoted, `${var@U}` uppercase, `${var@L}` lowercase\n- `declare -n ref=varname` nameref for indirect access\n- `wait -n` wait for any background job\n- `$EPOCHSECONDS`, `$EPOCHREALTIME` -- timestamps without forking `date`\n\n## Linux-Specific\n\n- GNU coreutils differ from macOS: `sed -i` (no `''` suffix), `grep -P` (PCRE support), `readlink -f` (canonical path)\n- `timeout 30s cmd` to prevent automation hangs\n\n## ShellCheck\n\nRun `shellcheck --enable=all script.sh`. Key rules:\n- **SC2155**: Separate declaration from assignment\n- **SC2086**: Double-quote variables\n- **SC2046**: Quote command substitutions\n- **SC2164**: `cd dir || exit`\n- **SC2327/SC2328**: Use `${BASH_REMATCH[n]}` not `$n` for regex captures\n\nPre-commit: `shellcheck *.sh && shfmt -i 2 -ci -d *.sh`\n\n## Verify\n\nRun `shellcheck --enable=all` and `shfmt -d` with zero warnings before declaring done. Test edge cases: empty input, missing files, spaces in paths.","tags":["linux","bash","scripting","skills","iliaal","agent-skills","ai-coding-assistant","ai-tools","claude-code"],"capabilities":["skill","source-iliaal","skill-linux-bash-scripting","topic-agent-skills","topic-ai-coding-assistant","topic-ai-tools","topic-claude-code","topic-skills"],"categories":["ai-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/iliaal/ai-skills/linux-bash-scripting","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add iliaal/ai-skills","source_repo":"https://github.com/iliaal/ai-skills","install_from":"skills.sh"}},"qualityScore":"0.456","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 13 github stars · SKILL.md body (5,702 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-05-18T19:07:02.408Z","embedding":null,"createdAt":"2026-05-09T01:05:35.412Z","updatedAt":"2026-05-18T19:07:02.408Z","lastSeenAt":"2026-05-18T19:07:02.408Z","tsv":"'-0':630 '-9':481,483,580,586 '/dev/null':347 '/etc/app/config.yml':407 '/old/new':614 '/path':260 '/usr/bin/env':42 '/var/lock':443 '0':58,70,112,113,202,304,324,415,444,482 '077':493 '1':307,331,334,346,352,355,369,402,419,425,455,465,468,475,479,480,486,523,538,596 '130':504 '2':72,317,319,332,353,375,429,453,472,476,524,525,751 '30s':702 '4.4':25,646 '5':417,647 '64':218 '78':221 '9':442,448 'access':667 'alreadi':450 'alway':92 'anti':540 'anti-pattern':539 'argument':296 'arithmet':153 'array':126,179,266 'assign':188,720 'atom':382,392,405 'autom':706 'background':673 'backoff':410 'backtick':155 'bad':542 'basenam':612 'bash':3,6,9,24,41,43,56,68,110,200,205,243,298,342,364,391,411,440,461,514,645,736 'behavior':146 'bodi':104 'boundari':490 'break':326,335 'build':176 'cach':622 'caller':512 'canon':699 'captur':743 'case':306,771 'cat':398,573 'cd':54,590,593,599,731 'check':341 'ci':752 'cleanup':500,502 'cmd':125,180,184,196,559,563,592,601,625,703 'code':192,214,232,510,566 'command':90,177,211,268,273,344,728 'commit':746 'concurr':438 'condit':151 'config':220,404 'constant':135,139 'continu':292 'core':119 'coreutil':685 'correct':508 'cp':379 'creat':93,496 'curl':359,432 'd':18,66,102,253,275,464,753,762 'data':568,572 'date':521,680 'debug':197 'declar':636,660,718,767 'delay':418,427,428 'delimit':246 'depend':340 'diagnost':228 'die':484,535 'differ':686 'dir':53,95,463,591,594,600,732 'dirnam':55,609 'done':258,295,337,430,768 'doubl':723 'double-quot':722 'dri':361,367,372 'dry-run':360 'dst':381 'e':79,290 'echo':144,567,620 'edg':770 'eeuo':45 'els':376 'empti':772 'enabl':14,115,711,758 'end':156 'ensur':462,469 'env':166 'epochrealtim':676 'epochsecond':675 'err':73,81 'errexit':50,86,88 'error':63,532,534,536 'esac':336 'eval':173 'everi':122 'ex':216,219 'exec':441 'exit':78,98,191,213,226,231,323,333,354,454,503,509,537,565,595,733 'expans':123,604 'expr':618 'extern':606 'f':183,254,257,262,286,291,294,545,549,698 'failur':240 'fals':300 'fi':377 'file':164,208,247,276,383,498,574,578,775 'find':259,277,553 'first':582,585 'fix':543 'flag':148 'flock':446 'fork':679 'foundat':40 'fssl':433 'function':84,129,134 'generat':403 'glob':279 'gnu':23,684 'grep':162,181,575,576,621,644,693 'gt':303 'guard':109,284 'h':320 'hang':707 'help':321 'idempot':456 'if':250 'indirect':666 'info':526,528 'inherit':49,85 'input':175,477,773 'instead':641 'int':505 'interpret':149 'invalid':485 'isecond':522 'iter':242 'job':674 'jq':357 'key':714 'kill':579,583 'l':471,658 'last':239,588 'line':209,272 'lineno':71,203 'link':470 'linux':2,5,27,682 'linux-bash-script':1 'linux-specif':681 'ln':473 'local':127,131,186,193,394,413,557,560 'lock':436,445 'log':264,513,515,527,530,533 'lookup':640 'lowercas':659 'ls':547 'maco':688 'macos/bsd':29 'magic':223 'main':106,114 'map':638 'match':283 'max':416,423 'miss':349,774 'mkdir':466 'mktemp':101,397 'must':169 'mv':400 'n':67,142,330,351,374,414,422,447,452,520,571,661,669,738,740 'name':212,263 'nameref':664 'never':172 'no-match':281 'nproc':632 'nul':245 'nul-delimit':244 'number':224 'o':314 'oper':457 'option':157 'output':269,301,315,316 'p':60,467,631,694 'parallel':634 'paramet':603 'pars':297 'pass':12 'pat':182,577 'path':33,161,607,610,700,778 'pattern':163,339,541 'pcre':695 'per':210 'perform':602 'pid':581,584 'pipe':235 'pipefail':46 'pipelin':227 'pipestatus':229 'place':390 'posix':36 'posix-on':35 'pre':745 'pre-commit':744 'predict':145 'preserv':190,507,564 'prevent':437,705 'print0':265,278,554 'printf':62,140,327,348,371,449,516,569 'process':248,256,293 'produc':8 'product':338 'propag':80,87 'ps4':199 'pwd':59 'q':650 'quot':121,653,724,727 'r':132,252 'read':251,556 'readarray':270,274 'readlink':697 'readon':51,136,215 'ref':662 'regex':742 'rematch':737 'renam':388 'repeat':643 'requir':165,343,356,358 'rerun':460 'resort':589 'restrict':38 'result':623 'retri':408,412,431 'return':424 'reus':627 'rf':76,160 'rm':75,159 'rule':120,715 'run':362,365,368,378,439,451,709,756 'safe':241,458 'sc2046':726 'sc2086':721 'sc2155':716 'sc2164':730 'sc2327/sc2328':734 'script':4,7,10,39,52,138,435,489,495 'script.sh':713 'sed':616,689 'sensit':497 'separ':185,717 'set':44,171 'sh':748,754 'shell':652 'shell-quot':651 'shellcheck':13,708,710,747,757 'shfmt':17,749,761 'shift':313,318,325 'shopt':47 'show':207,230 'signal':499 'skill' 'skill-linux-bash-scripting' 'sleep':426 'sourc':57,69,108,111,116,201 'source-iliaal' 'space':776 'specif':683 'src':380 'stage':236 'subshel':598 'substitut':91,729 'suffix':692 'support':696 'target':22 'temp':94,387 'term':506 'test':118,769 'timeout':701 'timestamp':677 'tmp':395,396,399,401 'tmpdir':77,100 'topic-agent-skills' 'topic-ai-coding-assistant' 'topic-ai-tools' 'topic-claude-code' 'topic-skills' 'trace':198 'trap':61,74,82,99,501 'true':312 'txt':288 'type':261 'u':655 'umask':492 'unknown':328 'uppercas':656 'url':434 'usag':217,322 'use':735 'user':174 'v':309,345 'val':194,195,624,628 'valid':478,487 'var':124,167,168,613,649,654,657 'variabl':130,725 'varnam':663 'verbos':299,310,311 'verifi':755 'wait':668,670 'warn':21,529,531,765 'window':32 'without':678 'work':635 'workaround':30 'wrap':103 'wrapper':363 'write':384,385,393,406 'x':206,558,561,562,648 'xarg':629 'zero':20,764","prices":[{"id":"74249912-5f38-4b96-a00e-05cc9f6cecea","listingId":"8d1ea825-c6fd-42fc-9ed7-e8d44814fa76","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"iliaal","category":"ai-skills","install_from":"skills.sh"},"createdAt":"2026-05-09T01:05:35.412Z"}],"sources":[{"listingId":"8d1ea825-c6fd-42fc-9ed7-e8d44814fa76","source":"github","sourceId":"iliaal/ai-skills/linux-bash-scripting","sourceUrl":"https://github.com/iliaal/ai-skills/tree/master/skills/linux-bash-scripting","isPrimary":false,"firstSeenAt":"2026-05-09T01:05:35.412Z","lastSeenAt":"2026-05-18T19:07:02.408Z"}],"details":{"listingId":"8d1ea825-c6fd-42fc-9ed7-e8d44814fa76","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"iliaal","slug":"linux-bash-scripting","github":{"repo":"iliaal/ai-skills","stars":13,"topics":["agent-skills","ai-coding-assistant","ai-tools","claude-code","skills"],"license":"mit","html_url":"https://github.com/iliaal/ai-skills","pushed_at":"2026-05-16T13:15:17Z","description":"Curated collection of agent skills for AI coding assistants.","skill_md_sha":"be250729fdbc42c9cfadbe8d32e980e1cefe907f","skill_md_path":"skills/linux-bash-scripting/SKILL.md","default_branch":"master","skill_tree_url":"https://github.com/iliaal/ai-skills/tree/master/skills/linux-bash-scripting"},"layout":"multi","source":"github","category":"ai-skills","frontmatter":{"name":"linux-bash-scripting","description":">-"},"skills_sh_url":"https://skills.sh/iliaal/ai-skills/linux-bash-scripting"},"updatedAt":"2026-05-18T19:07:02.408Z"}}