api: YAML JSON TOON Database
version: 1.0.0
format: json
dataset:
  id: 46
  slug: shell-scripting-guide
  title: Shell Scripting Guide (Bash)
  description: "Comprehensive reference for Bash shell scripting: variables, control flow, functions, error handling, debugging, and best practices."
  summary: "A guide to Bash scripting by topic with examples: variables and expansion, control flow, functions, error handling, file operations, arrays and maps, debugging and best practices."
  use_when:
    - You are writing or reviewing a shell script.
    - You need a safe idiom for a common scripting task.
  caveats:
    - Bash-specific features (arrays, [[ ]]) are not available in POSIX sh; set the shebang accordingly.
    - Use set -euo pipefail and quote variables, and consider a different language for complex logic.
  related:
    - file-operations
    - git-essential-commands
    - unix-text-processing-commands
    - cicd-pipeline-stages
  category: Unix Commands
  category_slug: unix-commands
  tags: bash,shell,scripting,unix,linux,automation,devops
  view_count: 0
  created_at: 1777673262
  updated_at: 1777673262
  entry_count: 8
  fields:
    - section: sections
      field: topic
      type: string
      example: Variables and Expansion
    - section: sections
      field: examples
      type: array
      example: "[4 items]"
data:
  sections:
    - topic: Variables and Expansion
      examples:
        - name: Simple assignment
          code: "name=\"John\"\necho \"Hello, $name\""
        - name: Command substitution
          code: "current_dir=$(pwd)\necho \"We are in $current_dir\""
        - name: Default values
          code: "echo \"${PORT:-8080}\"  # prints 8080 if PORT unset\necho \"${PORT:=8080}\"  # sets PORT to 8080 if unset\necho \"${PORT:?Error: PORT required}\"  # exits if unset"
        - name: String manipulation
          code: "str=\"hello_world.txt\"\necho \"${str%.*}\"   # hello_world (remove shortest suffix)\necho \"${str##*.}\"  # txt (remove longest prefix)\necho \"${str/_/-}\"   # hello-world.txt (replace first _)"
    - topic: Control Flow
      examples:
        - name: If statement
          code: "if [ -f \"$file\" ]; then\n    echo \"File exists\"\nelif [ -d \"$file\" ]; then\n    echo \"Is a directory\"\nelse\n    echo \"Not found\"\nfi"
        - name: For loop
          code: "for item in \"${array[@]}\"; do\n    echo \"Processing: $item\"\ndone\n\n# Or with range\nfor i in {1..10}; do\n    echo \"Count: $i\"\ndone"
        - name: While loop
          code: "while IFS= read -r line; do\n    echo \"Line: $line\"\ndone < \"input.txt\""
        - name: Case statement
          code: "case \"$1\" in\n    start) echo \"Starting...\";;\n    stop)  echo \"Stopping...\";;\n    restart) echo \"Restarting...\";;\n    *)     echo \"Usage: $0 {start|stop|restart}\"; exit 1;;\nesac"
    - topic: Functions
      examples:
        - name: Define and call
          code: "greet() {\n    local name=\"$1\"\n    echo \"Hello, $name!\"\n}\n\ngreet \"World\"  # Hello, World!"
        - name: Return values
          code: "is_even() {\n    local num=$1\n    return $(( num % 2 ))\n}\n\nif is_even 42; then\n    echo \"Even\"\nelse\n    echo \"Odd\"\nfi"
        - name: Output capture
          code: "get_date() {\n    date \"+%Y-%m-%d\"\n}\n\ntoday=$(get_date)\necho \"Today is $today\""
    - topic: Error Handling
      examples:
        - name: Exit on error
          code: "set -e  # Exit immediately on error\nset -u  # Error on undefined variables\nset -o pipefail  # Fail pipeline on first error\n\n# Combined\nset -euo pipefail"
        - name: Trap signals
          code: "cleanup() {\n    echo \"Cleaning up...\"\n    rm -f /tmp/tempfile\n    exit\n}\n\ntrap cleanup EXIT SIGINT SIGTERM"
        - name: Check command success
          code: "if ! command -v docker &> /dev/null; then\n    echo \"Docker is not installed\"\n    exit 1\nfi"
    - topic: File Operations
      examples:
        - name: Read file line by line
          code: "while IFS= read -r line; do\n    echo \"$line\"\ndone < \"input.txt\""
        - name: Check file conditions
          code: "if [ -f \"$file\" ]; then echo \"regular file\"; fi\nif [ -d \"$dir\" ]; then echo \"directory\"; fi\nif [ -x \"$bin\" ]; then echo \"executable\"; fi\nif [ -z \"$str\" ]; then echo \"empty string\"; fi\nif [ -n \"$str\" ]; then echo \"non-empty\"; fi"
        - name: Temp files
          code: "tempfile=$(mktemp)\necho \"Writing to $tempfile\"\n# ... use it ...\nrm -f \"$tempfile\""
    - topic: Arrays and Maps
      examples:
        - name: Indexed array
          code: "fruits=(\"apple\" \"banana\" \"cherry\")\necho \"${fruits[0]}\"  # apple\necho \"${#fruits[@]}\"  # length 3\necho \"${fruits[@]}\"   # all elements"
        - name: Associative array (Bash 4+)
          code: "declare -A config\nconfig[\"host\"]=\"localhost\"\nconfig[\"port\"]=8080\n\necho \"${config[host]}\"  # localhost"
    - topic: Debugging
      examples:
        - name: Enable debug mode
          code: "set -x  # Print commands and their arguments as executed\n# ... debug code ...\nset +x  # Disable debug\n\n# Or run script with:\n# bash -x script.sh"
        - name: Check syntax without running
          code: "bash -n script.sh\n# Returns silently if syntax is valid"
        - name: ShellCheck static analysis
          code: "# Install: apt install shellcheck / brew install shellcheck\n# Run: shellcheck script.sh\n# Catches: unquoted variables, missing shebang, common pitfalls"
    - topic: Best Practices
      examples:
        - name: Script header
          code: "#!/usr/bin/env bash\nset -euo pipefail\nIFS=$'\\n\\t'"
        - name: Usage function
          code: "usage() {\n    cat <<EOF\nUsage: $0 [options]\n  -h    Show help\n  -v    Verbose mode\n  -f    Input file\nEOF\n    exit 1\n}\n\nwhile getopts \"hf:v\" opt; do\n    case $opt in\n        h) usage;;\n        f) file=\"$OPTARG\";;\n        v) verbose=true;;\n        *) usage;;\n    esac\ndone"
        - name: Portable scripting
          code: "# Prefer POSIX sh -c over bashisms when portability matters\n# Use printf instead of echo for consistent behavior\n# Quote all variable expansions\n# Use $(...) over backticks"
