搜索

PythonReactSEOPDF
GitHub Skill

shell-error-handling

Use when implementing error handling, cleanup routines, or debugging in shell scripts. Covers traps, exit codes, and robust error patterns.

TheBushidoCollective☆ 75 仓库 Stars10 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Shell Error Handling

Patterns for robust error handling, cleanup, and debugging in shell scripts.

Exit Codes

Standard Exit Codes
Code Meaning
0 Success
1 General error
2 Misuse of shell command
126 Command not executable
127 Command not found
128+N Fatal signal N
130 Ctrl+C (SIGINT)
Checking Exit Status
# Check last command's exit status
if ! command; then
    echo "Command failed with status $?" >&2
    exit 1
fi

# Alternative pattern
command || {
    echo "Command failed" >&2
    exit 1
}

# Capture exit status
command
status=$?
if (( status != 0 )); then
    echo "Failed with status $status" >&2
fi

Trap for Cleanup

Basic Cleanup Pattern
#!/usr/bin/env bash
set -euo pipefail

cleanup() {
    local exit_code=$?
    # Remove temporary files
    rm -f "$TEMP_FILE" 2>/dev/null || true
    exit "$exit_code"
}

trap cleanup EXIT

TEMP_FILE=$(mktemp)
# Script continues...
# cleanup runs automatically on exit
Handling Multiple Signals
#!/usr/bin/env bash
set -euo pipefail

cleanup() {
    echo "Cleaning up..." >&2
    rm -rf "$WORK_DIR" 2>/dev/null || true
}

handle_interrupt() {
    echo "Interrupted by user" >&2
    cleanup
    exit 130
}

trap cleanup EXIT
trap handle_interrupt INT TERM

WORK_DIR=$(mktemp -d)
Trap Best Practices
# Preserve original exit code in cleanup
cleanup() {
    local exit_code=$?
    # Cleanup operations here
    rm -f "$temp_file" 2>/dev/null || true
    # Restore exit code
    exit "$exit_code"
}

# Use || true for optional cleanup
trap 'rm -f "$temp_file" 2>/dev/null || true' EXIT

Error Reporting

Standard Error Output
# Always write errors to stderr
echo "Error: Something went wrong" >&2

# Error function
error() {
    echo "Error: $*" >&2
}

# Die function - error and exit
die() {
    echo "Fatal: $*" >&2
    exit 1
}

# Usage
[[ -f "$config" ]] || die "Config file not found: $config"
Verbose Logging
#!/usr/bin/env bash
set -euo pipefail

VERBOSE="${VERBOSE:-false}"

log() {
    if [[ "$VERBOSE" == "true" ]]; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
    fi
}

error() {
    echo "[ERROR] $*" >&2
}

log "Starting script"
log "Processing file: $file"

Defensive Programming

Check Prerequisites
# Check required commands exist
require_command() {
    command -v "$1" >/dev/null 2>&1 || {
        echo "Error: Required command '$1' not found" >&2
        exit 1
    }
}

require_command jq
require_command curl
require_command shellcheck
Validate Input
# Validate arguments
if [[ $# -lt 2 ]]; then
    echo "Usage: $0 <source> <destination>" >&2
    exit 1
fi

source_file="$1"
dest_dir="$2"

# Validate file exists
[[ -f "$source_file" ]] || {
    echo "Error: Source file not found: $source_file" >&2
    exit 1
}

# Validate directory
[[ -d "$dest_dir" ]] || {
    echo "Error: Destination directory not found: $dest_dir" >&2
    exit 1
}
Safe Temporary Files
# Create secure temp file
TEMP_FILE=$(mktemp) || {
    echo "Error: Failed to create temp file" >&2
    exit 1
}

# Create secure temp directory
TEMP_DIR=$(mktemp -d) || {
    echo "Error: Failed to create temp directory" >&2
    exit 1
}

# Always clean up
trap 'rm -rf "$TEMP_FILE" "$TEMP_DIR" 2>/dev/null || true' EXIT

Debugging

Debug Mode
#!/usr/bin/env bash

# Enable debug mode via environment variable
if [[ "${DEBUG:-}" == "1" ]]; then
    set -x
fi

set -euo pipefail

# Or toggle with a flag
while getopts "d" opt; do
    case $opt in
        d) set -x ;;
        *) echo "Usage: $0 [-d]" >&2; exit 1 ;;
    esac
done
Trace Execution
# Enable tracing for specific section
set -x
problematic_code
set +x

# Trace with custom PS4
export PS4='+ ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x

Error Recovery Patterns

Retry Pattern
retry() {
    local max_attempts="${1:-3}"
    local delay="${2:-1}"
    shift 2
    local cmd=("$@")

    local attempt=1
    while (( attempt <= max_attempts )); do
        if "${cmd[@]}"; then
            return 0
        fi
        echo "Attempt $attempt failed, retrying in ${delay}s..." >&2
        sleep "$delay"
        (( attempt++ ))
    done

    echo "All $max_attempts attempts failed" >&2
    return 1
}

# Usage
retry 3 5 curl -f "http://example.com/api"
Fallback Pattern
# Try primary, fall back to secondary
get_config() {
    if [[ -f "$HOME/.config/myapp/config" ]]; then
        cat "$HOME/.config/myapp/config"
    elif [[ -f "/etc/myapp/config" ]]; then
        cat "/etc/myapp/config"
    else
        echo "Error: No config file found" >&2
        return 1
    fi
}

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-02-04
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!