Skilllibrary bash
install
source · Clone the upstream repo
git clone https://github.com/merceralex397-collab/skilllibrary
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/10-cli-systems-and-ops/bash" ~/.claude/skills/merceralex397-collab-skilllibrary-bash && rm -rf "$T"
manifest:
10-cli-systems-and-ops/bash/SKILL.mdsource content
Purpose
Write portable, safe Bash scripts with proper quoting, error handling, and ShellCheck compliance.
When to use this skill
- writing or editing
/.sh
scripts.bash - automating file operations, build steps, or deploy tasks in shell
- debugging quoting errors, glob expansion, or word-splitting bugs
- adding safety headers (
) to existing scriptsset -euo pipefail
Do not use this skill when
- building a Go CLI binary — prefer
cli-development-go - building a Python CLI tool — prefer
cli-development-python - writing systemd unit files — prefer
systemd-services - the script is a cross-platform
/.sh
pair — prefer.ps1cross-platform-shell
Procedure
- Add safety header — start every script with
and#!/usr/bin/env bash
.set -euo pipefail - Quote all expansions — wrap every
in double quotes:$variable
,"$var"
. Use"${arr[@]}"
to catch misses.shellcheck - Use
over[[ ]]
— double brackets prevent word-splitting and support regex. Never use unquoted[ ]
.test - Prefer
overprintf
—echo
behavior varies across platforms. Useecho
.printf '%s\n' "$msg" - Handle errors explicitly — use
for temp file removal. Check command exit codes withtrap cleanup EXIT
.if ! cmd; then - Use local variables in functions — declare with
to avoid polluting the global scope.local - Validate inputs — check
for argument count, validate file existence with$#
, reject empty strings.[[ -f "$path" ]] - Run ShellCheck — execute
and fix every warning before committing.shellcheck -o all script.sh
Key patterns
#!/usr/bin/env bash set -euo pipefail readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cleanup() { rm -f "${tmp_file:-}"; } trap cleanup EXIT main() { local input="${1:?Usage: $0 <input-file>}" [[ -f "$input" ]] || { printf 'File not found: %s\n' "$input" >&2; return 1; } local tmp_file tmp_file="$(mktemp)" # process... } main "$@"
Array iteration:
files=("$SCRIPT_DIR"/*.txt) for f in "${files[@]}"; do [[ -e "$f" ]] || continue process_file "$f" done
Decision rules
- Never use
or unquotedeval
in conditionals.$() - Redirect stderr for user-facing messages:
.echo "error" >&2 - Use
for constants,readonly
for function-scoped variables.local - Prefer
overcommand -v
for portability.which - If a script exceeds 200 lines, consider rewriting in Python or Go.
References
- https://www.shellcheck.net/
- https://mywiki.wooledge.org/BashPitfalls
- https://google.github.io/styleguide/shellguide.html
Related skills
— multi-OS shell scriptscross-platform-shell
— complex CLI toolscli-development-python
— debugging shell executionterminal-debugging
— system administration taskslinux-ubuntu-ops