claude-home/development/bash-troubleshooting.md
Cal Corum 4b7eca8a46
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: add YAML frontmatter to all 151 markdown files
Adds title, description, type, domain, and tags frontmatter to every
doc for improved KB semantic search. The description field is prepended
to every search chunk, and domain/type/tags enable filtered queries.

Type values: context, guide, runbook, reference, troubleshooting
Domain values match directory structure (networking, docker, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:00:44 -05:00

253 lines
4.9 KiB
Markdown

---
title: "Bash Script Troubleshooting"
description: "Troubleshooting guide for bash scripts covering debug modes (set -x), error traps, variable/parameter validation, file permission checks, process management, string comparison, and system resource monitoring."
type: troubleshooting
domain: development
tags: [bash, troubleshooting, debugging, scripting, error-handling, shell]
---
# Bash Script Troubleshooting Reference
## Script Debugging
### Enable debugging modes
```bash
#!/bin/bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
set -x # Print commands as they're executed (xtrace)
# Or run with debug flags
bash -x script.sh
bash -n script.sh # Check syntax without execution
```
### Common error handling
```bash
#!/bin/bash
set -euo pipefail
# Function to handle errors
error_handler() {
echo "Error occurred in script at line: $1" >&2
echo "Command that failed: $2" >&2
exit 1
}
# Set error trap
trap 'error_handler ${LINENO} "$BASH_COMMAND"' ERR
# Example with error checking
if ! command -v docker >/dev/null 2>&1; then
echo "Error: docker is not installed" >&2
exit 1
fi
```
## Variable and Parameter Issues
### Check if variables are set
```bash
# Check if variable is set and not empty
if [[ -z "${VAR:-}" ]]; then
echo "VAR is not set or empty"
exit 1
fi
# Set default values
VAR="${VAR:-default_value}"
VAR="${1:-default_value}" # For parameters
# Required variables
: "${REQUIRED_VAR:?Error: REQUIRED_VAR must be set}"
```
### Array debugging
```bash
# Declare array properly
declare -a array_name
array_name=("item1" "item2" "item3")
# Check array contents
declare -p array_name
printf '%s\n' "${array_name[@]}"
# Array length
echo "Array length: ${#array_name[@]}"
```
## File and Directory Issues
### File existence and permissions
```bash
# Check file existence
if [[ ! -f "$filename" ]]; then
echo "File $filename does not exist"
exit 1
fi
# Check directory existence
if [[ ! -d "$dirname" ]]; then
echo "Directory $dirname does not exist"
mkdir -p "$dirname"
fi
# Check permissions
if [[ ! -r "$filename" ]]; then
echo "File $filename is not readable"
exit 1
fi
if [[ ! -w "$filename" ]]; then
echo "File $filename is not writable"
exit 1
fi
```
### Path issues
```bash
# Get absolute path
filename="$(realpath "$1")"
dirname="$(dirname "$filename")"
basename="$(basename "$filename")"
# Change to script directory
cd "$(dirname "$0")"
```
## Process and Command Issues
### Command existence checking
```bash
# Check if command exists
if ! command -v docker >/dev/null 2>&1; then
echo "docker is required but not installed"
exit 1
fi
# Alternative method
if ! which docker >/dev/null 2>&1; then
echo "docker not found in PATH"
exit 1
fi
```
### Process management
```bash
# Check if process is running
if pgrep -x "process_name" >/dev/null; then
echo "Process is running"
else
echo "Process is not running"
fi
# Kill process safely
if pgrep -x "process_name" >/dev/null; then
pkill -x "process_name"
sleep 2
if pgrep -x "process_name" >/dev/null; then
pkill -9 -x "process_name"
fi
fi
```
## String and Text Processing
### String comparison issues
```bash
# Safe string comparison
string1="test"
string2=""
# Always quote variables
if [[ "$string1" == "test" ]]; then
echo "Match"
fi
# Check for empty strings
if [[ -z "$string2" ]]; then
echo "String is empty"
fi
if [[ -n "$string1" ]]; then
echo "String is not empty"
fi
```
### Input validation
```bash
# Validate numeric input
if ! [[ "$input" =~ ^[0-9]+$ ]]; then
echo "Error: Input must be a number"
exit 1
fi
# Validate email format (basic)
if ! [[ "$email" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
echo "Error: Invalid email format"
exit 1
fi
```
## System Resource Issues
### Disk space checking
```bash
# Check available disk space
available=$(df / | awk 'NR==2 {print $4}')
if [[ $available -lt 1000000 ]]; then # Less than 1GB
echo "Warning: Low disk space"
fi
# Check if directory has enough space
required_space=1000000 # 1GB in KB
available=$(df "$directory" | awk 'NR==2 {print $4}')
if [[ $available -lt $required_space ]]; then
echo "Error: Not enough disk space"
exit 1
fi
```
### Memory checking
```bash
# Check available memory
available_mem=$(free | awk 'NR==2 {print $7}')
if [[ $available_mem -lt 1000000 ]]; then # Less than 1GB
echo "Warning: Low available memory"
fi
```
## Debugging Techniques
### Add debug output
```bash
# Debug function
debug() {
if [[ "${DEBUG:-}" == "1" ]]; then
echo "DEBUG: $*" >&2
fi
}
# Usage
debug "Processing file: $filename"
```
### Temporary file handling
```bash
# Create temporary file safely
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
# Create temporary directory
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
```
### Script execution tracing
```bash
# Trace specific functions
trace_function() {
set -x
your_function_here
set +x
}
```