# Bash Script Code Structure Reference

## Section Order (固定顺序，不可打乱)

```
┌─────────────────────────────────────────────────────────────┐
│ 1. SHEBANG + METADATA                                       │
│    #!/usr/bin/env bash                                      │
│    # Author / Version / License / Last Updated              │
├─────────────────────────────────────────────────────────────┤
│ 2. ASCII CALL GRAPH                                         │
│    # main()                                                 │
│    #   ├── parse_args()                                     │
│    #   ├── check_dependencies()                             │
│    #   ├── business_function_1()                            │
│    #   │     └── helper_function()                          │
│    #   └── cleanup()                                        │
├─────────────────────────────────────────────────────────────┤
│ 3. GLOBAL CONSTANTS                                         │
│    readonly VERSION="1.0.0"                                 │
│    readonly SCRIPT_NAME="${0##*/}"                          │
│    readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"     │
├─────────────────────────────────────────────────────────────┤
│ 4. STRICT MODE                                              │
│    set -Eeuo pipefail                                       │
│    IFS=$' \t\n'                                             │
├─────────────────────────────────────────────────────────────┤
│ 5. CONFIGURABLE DEFAULTS                                    │
│    LOG_LEVEL="${LOG_LEVEL:-INFO}"                           │
│    DRY_RUN=false                                            │
│    VERBOSE=false                                            │
│    FORCE=false                                              │
├─────────────────────────────────────────────────────────────┤
│ 6. DEPENDENCY & ENVIRONMENT CHECKS                          │
│    check_bash_version()                                     │
│    check_dependencies()                                     │
│    check_permissions()                                      │
├─────────────────────────────────────────────────────────────┤
│ 7. LOGGING & ERROR HANDLING                                 │
│    log_debug() / log_info() / log_warn() / log_error()      │
│    die()                                                    │
│    run_cmd()                                                │
│    cleanup()                                                │
│    trap setup                                               │
├─────────────────────────────────────────────────────────────┤
│ 8. BUSINESS FUNCTIONS                                       │
│    (grouped by domain, each <50 lines)                      │
├─────────────────────────────────────────────────────────────┤
│ 9. MAIN + ENTRY                                             │
│    main() { parse_args; check_deps; do_work; }              │
│    main "$@"                                                │
└─────────────────────────────────────────────────────────────┘
```

## Strict Mode Explained

```bash
set -E          # ERR trap inherited by functions
set -e          # Exit on error
set -u          # Error on unset variables
set -o pipefail # Pipe fails if any command fails
```

Combined: `set -Eeuo pipefail`

## IFS Safety

```bash
# Default safe IFS
IFS=$' \t\n'

# When processing CSV or custom delimiter, use local override:
local IFS=','
read -ra fields <<< "$line"
```

## Variable Quoting Rules

| Context | Correct | Wrong |
|---------|---------|-------|
| Assignment | `var="$value"` | `var=$value` |
| Command arg | `cmd "$file"` | `cmd $file` |
| Array expansion | `"${arr[@]}"` | `${arr[@]}` |
| Intentional splitting | `$unquoted # > reason` | (must comment) |

## Readonly Constants Pattern

```bash
# Script metadata
readonly VERSION="1.0.0"
readonly SCRIPT_NAME="${0##*/}"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Exit codes
readonly E_SUCCESS=0
readonly E_GENERAL=1
readonly E_ARGS=2
readonly E_DEPS=3
readonly E_PERM=4
readonly E_NOTFOUND=5
```

## Temp Directory Pattern

```bash
# Create temp dir with automatic cleanup
TEMP_DIR=""

setup_temp() {
    TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${SCRIPT_NAME}.XXXXXX")"
    readonly TEMP_DIR
}

cleanup() {
    if [[ -n "${TEMP_DIR:-}" && -d "$TEMP_DIR" ]]; then
        rm -rf "$TEMP_DIR"
    fi
}

trap cleanup EXIT ERR INT TERM
```
