3.7 KiB
3.7 KiB
name, description
| name | description |
|---|---|
| shell-scripting | Specialized knowledge of Bash and Zsh scripting, shell automation, command-line tools, and scripting best practices. Use when the user needs to write, debug, or optimize shell scripts, work with command-line tools, automate tasks with bash/zsh, or asks for shell script help. |
Shell Scripting Expert
Expert guidance for writing robust, maintainable Bash and Zsh scripts with best practices for automation and command-line tool usage.
Script Structure Essentials
Start every script with:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -e: Exit on errorset -u: Error on undefined variablesset -o pipefail: Catch errors in pipesIFS=$'\n\t': Safer word splitting
Critical Best Practices
- Always quote variables:
"$variable"not$variable - Use
[[for conditionals (Bash):if [[ "$var" == "value" ]]; then - Check command existence:
if command -v git &> /dev/null; then - Avoid parsing
ls: Use globs orfindinstead - Use arrays for lists:
files=("file1" "file2")not space-separated strings - Handle errors with traps:
trap cleanup EXIT trap 'echo "Error on line $LINENO"' ERR
Common Patterns
Argument Parsing
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage; exit 0 ;;
-v|--verbose) VERBOSE=true; shift ;;
-*) echo "Unknown option: $1"; exit 1 ;;
*) break ;;
esac
done
Safe File Iteration
# Prefer this (handles spaces, newlines correctly):
while IFS= read -r -d '' file; do
echo "Processing: $file"
done < <(find . -type f -name "*.txt" -print0)
# Or with simple globs:
for file in *.txt; do
[[ -e "$file" ]] || continue # Skip if no matches
echo "Processing: $file"
done
User Confirmation
read -rp "Continue? [y/N] " response
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "Continuing..."
fi
Colored Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}Success${NC}"
echo -e "${RED}Error${NC}" >&2
Modern Tool Alternatives
When appropriate, suggest these modern replacements:
ripgrep(rg) → faster than grepfd→ faster than findfzf→ interactive filteringjq→ JSON processingyq→ YAML processingbat→ cat with syntax highlightingeza→ enhanced ls
Function Organization
usage() {
cat <<EOF
Usage: ${0##*/} [OPTIONS] <args>
Description of what this script does.
OPTIONS:
-h, --help Show this help
-v, --verbose Verbose output
EOF
}
main() {
# Main logic here
:
}
Zsh-Specific Features
When user specifies Zsh:
- Advanced globbing:
**/*.txt(recursive),*.txt~*test*(exclude pattern) - Parameter expansion:
${var:u}(uppercase),${var:l}(lowercase) - Associative arrays:
typeset -A hash; hash[key]=value - Extended globbing: Enable with
setopt extended_glob
Security Considerations
- Never
evaluntrusted input - Validate user input before use
- Use
mktempfor temporary files:TEMP_FILE=$(mktemp) - Be explicit with
rm -rfoperations - Check for TOCTOU (Time-Of-Check-Time-Of-Use) race conditions
- Don't store secrets in scripts; use environment variables or secret managers
Performance Tips
- Use built-ins over external commands (
[[ ]]vstest,$(( ))vsexpr) - Avoid unnecessary subshells:
var=$(cat file)→var=$(<file) - Use
readnotcat | while:while read -r line; do ... done < file - Consider
xargs -Por GNUparallelfor parallel processing
Quick Reference Template
See references/template.sh for a complete, production-ready script template with all best practices incorporated.