Claude-skill-registry bash-development
This skill should be used when the user asks to "write a bash script", "create a shell script", "implement bash function", "parse arguments in bash", "handle errors in bash", or mentions bash development, shell scripting, script templates, or modern bash patterns.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bash-development" ~/.claude/skills/majiayu000-claude-skill-registry-bash-development && rm -rf "$T"
skills/data/bash-development/SKILL.mdBash Development
Core patterns and best practices for Bash 5.1+ script development. Provides modern bash idioms, error handling, argument parsing, and pure-bash alternatives to external commands.
Script Foundation
Every script starts with the essential header:
#!/usr/bin/env bash set -euo pipefail
set options explained:
- Exit immediately on command failure-e
- Treat unset variables as errors-u
- Pipeline fails if any command fails-o pipefail
Script Metadata Pattern
SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}") SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) readonly SCRIPT_VERSION="1.0.0" readonly SCRIPT_NAME SCRIPT_DIR
Error Handling
Implement trap-based error handling for robust scripts:
handle_error() { local line="${1}" local exit_code="${2:-1}" printf '%s\n' "Error on line ${line}" >&2 exit "${exit_code}" } trap 'handle_error ${LINENO} $?' ERR cleanup() { # Cleanup logic here rm -f "${TEMP_FILE:-}" } trap cleanup EXIT
Argument Parsing
Standard argument parsing template:
usage() { cat <<EOF Usage: ${SCRIPT_NAME} [OPTIONS] <argument> Options: -h, --help Show this help message -v, --version Show version information -d, --debug Enable debug mode -f, --file Specify input file Examples: ${SCRIPT_NAME} file.txt ${SCRIPT_NAME} --debug file.txt EOF } main() { local debug=0 local input_file="" while [[ $# -gt 0 ]]; do case "${1}" in -h|--help) usage; exit 0 ;; -v|--version) printf '%s version %s\n' "${SCRIPT_NAME}" "${SCRIPT_VERSION}"; exit 0 ;; -d|--debug) debug=1; set -x; shift ;; -f|--file) input_file="${2}"; shift 2 ;; -*) printf 'Unknown option: %s\n' "${1}" >&2; usage; exit 1 ;; *) break ;; esac done # Validate required arguments if [[ $# -lt 1 ]]; then printf 'Missing required argument\n' >&2 usage exit 1 fi # Main logic here } main "$@"
Variable Best Practices
Always use curly braces and quote variables:
# Correct "${variable}" "${array[@]}" # Incorrect $variable ${array[*]} # Use [@] for proper iteration
Use readonly for constants:
readonly CONFIG_FILE="/etc/app/config" readonly -a VALID_OPTIONS=("opt1" "opt2" "opt3")
Note: Never use
readonly in sourced scripts - it causes errors on re-sourcing.
String Operations (Pure Bash)
Prefer native bash parameter expansion over external tools:
# Trim whitespace trimmed="${string#"${string%%[![:space:]]*}"}" trimmed="${trimmed%"${trimmed##*[![:space:]]}"}" # Lowercase/Uppercase (Bash 4+) lower="${string,,}" upper="${string^^}" # Substring extraction substring="${string:0:10}" # First 10 chars suffix="${string: -5}" # Last 5 chars # Replace patterns replaced="${string//old/new}" # Replace all replaced="${string/old/new}" # Replace first # Strip prefix/suffix no_prefix="${string#prefix}" # Shortest match no_prefix="${string##*/}" # Longest match (basename) no_suffix="${string%suffix}" # Shortest match no_suffix="${string%%/*}" # Longest match
Array Operations
# Declaration declare -a indexed_array=() declare -A assoc_array=() # Safe iteration with nullglob shopt -s nullglob for file in *.txt; do process "${file}" done shopt -u nullglob # Array length length="${#array[@]}" # Append element array+=("new_element") # Iterate with index for i in "${!array[@]}"; do printf '%d: %s\n' "${i}" "${array[i]}" done
File Operations
# Read file to string content="$(<"${file}")" # Read file to array (Bash 4+) mapfile -t lines < "${file}" # Check file conditions [[ -f "${file}" ]] # Regular file exists [[ -d "${dir}" ]] # Directory exists [[ -r "${file}" ]] # Readable [[ -w "${file}" ]] # Writable [[ -x "${file}" ]] # Executable [[ -s "${file}" ]] # Non-empty # Safe temp file creation temp_file=$(mktemp) trap 'rm -f "${temp_file}"' EXIT
Conditional Expressions
Use
[[ ]] for conditionals (bash-specific, more powerful):
# String comparisons [[ "${var}" == "value" ]] # Equality [[ "${var}" == pattern* ]] # Glob matching [[ "${var}" =~ ^regex$ ]] # Regex matching # Numeric comparisons (( num > 10 )) # Arithmetic comparison [[ "${num}" -gt 10 ]] # Traditional syntax # Compound conditions [[ -f "${file}" && -r "${file}" ]] [[ "${opt}" == "a" || "${opt}" == "b" ]]
Utility Functions
# Check command existence command_exists() { command -v "${1}" >/dev/null 2>&1 } # Get script directory (resolves symlinks) get_script_dir() { local source="${BASH_SOURCE[0]}" while [[ -L "${source}" ]]; do local dir=$(cd -P "$(dirname "${source}")" && pwd) source=$(readlink "${source}") [[ "${source}" != /* ]] && source="${dir}/${source}" done cd -P "$(dirname "${source}")" && pwd } # Conditional sudo run_privileged() { if [[ "${EUID}" -eq 0 ]]; then "$@" elif command_exists sudo; then sudo "$@" else printf 'Error: root privileges required\n' >&2 return 1 fi }
Performance Guidelines
- Use builtins over external commands when possible
- Batch operations instead of loops for large datasets
- Use
overprintf
for portability and controlecho - Avoid unnecessary subshells in tight loops
- Use
over[[ ]]
for string comparisons[ ]
Additional Resources
Reference Files
For detailed patterns and examples:
- bash_example_file.sh - Complete script template
- bash_example_includes.bash - Reusable utility functions
- bash-agent-notes.markdown - Context-aware review guidance
- pure-bash-bible-strings.md - String manipulation patterns
- pure-bash-bible-arrays.md - Array operations
- pure-bash-bible-files.md - File handling patterns
- pure-bash-bible-variables.md - Parameter expansion reference