Skip to content

8.2 指令碼編寫

在上一節中,我們學習了命令組合的基礎知識。在本節中,我們將學習如何將這些命令組合封裝成可重用的指令碼,以便更高效地自動化各種任務。

指令碼編寫概述

指令碼是將一系列命令和邏輯組合在一起的可執行檔案。使用指令碼可以:

  • 提高效率 :自動化重複性任務
  • 減少錯誤 :避免手動操作的錯誤
  • 便於維護 :集中管理複雜的邏輯
  • 易於分享 :方便與團隊成員共享

Bash 脚本基础

1. 脚本结构

一個基本的 Bash 指令碼包含以下元素:

bash
#### 示例:基本脚本结构

    bash


    #!/bin/bash

    # 脚本描述
    # 作者:Your Name
    # 日期:2026-01-01

    # 设置脚本选项
    set -e  # 遇到错误立即退出
    set -u  # 使用未定义变量时报错
    set -o pipefail  # 管道中任何命令失败都导致整个管道失败

    # 定义变量
    PROJECT_DIR="./myproject"
    MODEL="sonnet"

    # 定义函数
    main() {
      echo "开始执行脚本"
      setup_environment
      generate_code
      run_tests
      echo "脚本执行完成"
    }

    # 执行主函数
    main

#### 脚本元素说明
  • #!/bin/bash:Shebang 行,指定指令碼直譯器
  • set -e:遇到錯誤立即退出
  • set -u:使用未定義變數時報錯
  • set -o pipefail:管道中任何命令失敗都導致整個管道失敗
  • #:註釋符號
bash
### 2\. 变量和参数

#### 示例:定义和使用变量

    bash


    #!/bin/bash

    # 定义变量
    PROJECT_DIR="./myproject"
    MODEL="sonnet"
    OUTPUT_FORMAT="json"
    VERBOSE=true

    # 使用变量
    echo "项目目录: $PROJECT_DIR"
    echo "模型: $MODEL"

    # 条件使用变量
    if [ "$VERBOSE" = true ]; then
      claude --model "$MODEL" -p "分析项目" --verbose
    else
      claude --model "$MODEL" -p "分析项目"
    fi

#### 示例:使用位置参数

    bash


    #!/bin/bash

    # 使用位置参数
    PROJECT_DIR=$1
    MODEL=${2:-sonnet}  # 默认值为 sonnet
    OUTPUT_FORMAT=${3:-json}

    # 检查参数
    if [ -z "$PROJECT_DIR" ]; then
      echo "错误:必须指定项目目录"
      echo "用法: $0 <项目目录> [模型] [输出格式]"
      exit 1
    fi

    # 使用参数
    claude --model "$MODEL" \
           --add-dir "$PROJECT_DIR" \
           -p "分析项目" \
           --output-format "$OUTPUT_FORMAT"

#### 示例:使用命名参数

    bash


    #!/bin/bash

    # 定义命名参数
    while getopts "d:m:f:v" opt; do
      case $opt in
        d) PROJECT_DIR="$OPTARG" ;;
        m) MODEL="$OPTARG" ;;
        f) OUTPUT_FORMAT="$OPTARG" ;;
        v) VERBOSE=true ;;
        \?) echo "无效选项: -$OPTARG" >&2; exit 1 ;;
      esac
    done

    # 设置默认值
    PROJECT_DIR=${PROJECT_DIR:-./myproject}
    MODEL=${MODEL:-sonnet}
    OUTPUT_FORMAT=${OUTPUT_FORMAT:-json}
    VERBOSE=${VERBOSE:-false}

    # 使用参数
    if [ "$VERBOSE" = true ]; then
      echo "项目目录: $PROJECT_DIR"
      echo "模型: $MODEL"
      echo "输出格式: $OUTPUT_FORMAT"
    fi

    claude --model "$MODEL" \
           --add-dir "$PROJECT_DIR" \
           -p "分析项目" \
           --output-format "$OUTPUT_FORMAT"

### 3\. 函数定义

#### 示例:定义和使用函数

    bash


    #!/bin/bash

    # 定义函数
    setup_environment() {
      echo "设置环境..."
      claude --add-dir ./src --add-dir ./tests --add-dir ./config
    }

    generate_code() {
      echo "生成代码..."
      claude -p "生成代码"
    }

    run_tests() {
      echo "运行测试..."
      claude -p "运行测试"
    }

    # 定义主函数
    main() {
      setup_environment
      generate_code
      run_tests
    }

    # 执行主函数
    main

#### 示例:带参数的函数

    bash


    #!/bin/bash

    # 定义带参数的函数
    analyze_file() {
      local file=$1
      local model=${2:-sonnet}

      echo "分析文件: $file"
      claude --model "$model" -p "分析 $file 的代码质量"
    }

    # 使用函数
    analyze_file main.py
    analyze_file utils.js opus

#### 示例:带返回值的函数

    bash


    #!/bin/bash

    # 定义带返回值的函数
    get_model() {
      local task_type=$1

      case $task_type in
        "code_review")
          echo "sonnet"
          ;;
        "generation")
          echo "opus"
          ;;
        *)
          echo "sonnet"
          ;;
      esac
    }

    # 使用函数
    MODEL=$(get_model "code_review")
    echo "使用的模型: $MODEL"

### 4\. 条件判断

#### 示例:if 语句

    bash


    #!/bin/bash

    # 检查文件是否存在
    if [ -f "config.json" ]; then
      echo "配置文件存在"
      claude -p "使用配置文件"
    else
      echo "配置文件不存在"
      claude -p "使用默认配置"
    fi

    # 检查命令执行结果
    if claude -p "检查代码质量"; then
      echo "代码质量检查通过"
    else
      echo "代码质量检查失败"
      exit 1
    fi

    # 多条件判断
    if [ -f "config.json" ] && [ -f "settings.json" ]; then
      echo "所有配置文件都存在"
    elif [ -f "config.json" ]; then
      echo "只有 config.json 存在"
    else
      echo "配置文件不存在"
    fi

#### 示例:case 语句

    bash


    #!/bin/bash

    # 使用 case 语句
    TASK_TYPE=$1

    case $TASK_TYPE in
      "review")
        echo "执行代码审查"
        claude -p "审查代码"
        ;;
      "test")
        echo "执行测试"
        claude -p "运行测试"
        ;;
      "deploy")
        echo "执行部署"
        claude -p "部署应用"
        ;;
      *)
        echo "未知任务类型: $TASK_TYPE"
        echo "支持的任务类型: review, test, deploy"
        exit 1
        ;;
    esac

### 5\. 循环结构

#### 示例:for 循环

    bash


    #!/bin/bash

    # 遍历文件
    for file in *.py; do
      echo "处理文件: $file"
      claude -p "优化 $file 的性能"
    done

    # 遍历数组
    projects=("frontend" "backend" "api")
    for project in "${projects[@]}"; do
      echo "处理项目: $project"
      claude --add-dir "./$project" -p "分析项目"
    done

    # 数字循环
    for i in {1..5}; do
      echo "执行第 $i 次迭代"
      claude -p "执行任务 $i"
    done

#### 示例:while 循环

    bash


    #!/bin/bash

    # 持续监控文件变化
    while inotifywait -e modify *.py; do
      echo "检测到文件变化"
      claude -p "重新分析代码"
    done

    # 读取文件内容
    while IFS= read -r line; do
      echo "处理行: $line"
      claude -p "处理: $line"
    done < input.txt

    # 条件循环
    count=0
    while [ $count -lt 5 ]; do
      echo "计数: $count"
      claude -p "执行任务 $count"
      ((count++))
    done

### 6\. 错误处理

#### 示例:基本错误处理

    bash


    #!/bin/bash

    # 设置错误处理
    set -e

    # 检查命令是否成功
    if ! claude -p "生成代码"; then
      echo "错误:代码生成失败"
      exit 1
    fi

    # 使用 trap 捕获错误
    trap 'echo "发生错误,退出码: $?"' ERR

    claude -p "执行任务1"
    claude -p "执行任务2"
    claude -p "执行任务3"

#### 示例:高级错误处理

    bash


    #!/bin/bash

    # 定义错误处理函数
    handle_error() {
      local exit_code=$1
      local line_number=$2
      echo "错误发生在第 $line_number 行,退出码: $exit_code"

      # 清理操作
      cleanup

      exit $exit_code
    }

    # 设置错误处理
    trap 'handle_error $? $LINENO' ERR

    # 定义清理函数
    cleanup() {
      echo "执行清理操作..."
      rm -f temp_files/*
    }

    # 执行任务
    claude -p "执行任务1"
    claude -p "执行任务2"
    claude -p "执行任务3"

    # 清理
    cleanup

## 实用脚本示例

### 1\. 代码审查脚本

    bash


    #!/bin/bash

    # 代码审查脚本
    # 用法: ./code_review.sh [文件或目录] [模型]

    set -e

    # 参数处理
    TARGET=${1:-.}
    MODEL=${2:-sonnet}

    # 检查目标是否存在
    if [ ! -e "$TARGET" ]; then
      echo "错误:目标不存在: $TARGET"
      exit 1
    fi

    # 检查是文件还是目录
    if [ -f "$TARGET" ]; then
      echo "审查文件: $TARGET"
      claude --model "$MODEL" -p "审查 $TARGET 的代码质量、安全性和性能"
    elif [ -d "$TARGET" ]; then
      echo "审查目录: $TARGET"
      claude --model "$MODEL" --add-dir "$TARGET" -p "审查目录中的所有文件"
    else
      echo "错误:不支持的目标类型"
      exit 1
    fi

### 2\. 自动化测试脚本

    bash


    #!/bin/bash

    # 自动化测试脚本
    # 用法: ./auto_test.sh [测试类型]

    set -e

    # 参数处理
    TEST_TYPE=${1:-all}

    # 定义测试函数
    run_unit_tests() {
      echo "运行单元测试..."
      claude -p "生成单元测试用例"
      claude -p "运行单元测试"
    }

    run_integration_tests() {
      echo "运行集成测试..."
      claude -p "生成集成测试用例"
      claude -p "运行集成测试"
    }

    run_e2e_tests() {
      echo "运行端到端测试..."
      claude -p "生成端到端测试用例"
      claude -p "运行端到端测试"
    }

    # 根据测试类型执行测试
    case $TEST_TYPE in
      "unit")
        run_unit_tests
        ;;
      "integration")
        run_integration_tests
        ;;
      "e2e")
        run_e2e_tests
        ;;
      "all")
        run_unit_tests
        run_integration_tests
        run_e2e_tests
        ;;
      *)
        echo "错误:未知测试类型: $TEST_TYPE"
        echo "支持的测试类型: unit, integration, e2e, all"
        exit 1
        ;;
    esac

    echo "所有测试完成"

### 3\. 文档生成脚本

    bash


    #!/bin/bash

    # 文档生成脚本
    # 用法: ./generate_docs.sh [输出目录]

    set -e

    # 参数处理
    OUTPUT_DIR=${1:-./docs}

    # 创建输出目录
    mkdir -p "$OUTPUT_DIR"

    # 提取函数文档
    echo "提取函数文档..."
    claude -p "提取所有函数的文档注释" --output-format json > functions.json

    # 提取类文档
    echo "提取类文档..."
    claude -p "提取所有类的文档注释" --output-format json > classes.json

    # 生成 Markdown 文档
    echo "生成 Markdown 文档..."
    claude -p "根据提取的信息生成 Markdown 文档" \
      --input-format json \
      --output-format markdown \
      > "$OUTPUT_DIR/API.md"

    # 生成 HTML 文档
    echo "生成 HTML 文档..."
    claude -p "根据提取的信息生成 HTML 文档" \
      --input-format json \
      --output-format html \
      > "$OUTPUT_DIR/API.html"

    echo "文档生成完成: $OUTPUT_DIR"

### 4\. 项目分析脚本

    bash


    #!/bin/bash

    # 项目分析脚本
    # 用法: ./analyze_project.sh [项目目录] [输出格式]

    set -e

    # 参数处理
    PROJECT_DIR=${1:-.}
    OUTPUT_FORMAT=${2:-json}

    # 检查项目目录
    if [ ! -d "$PROJECT_DIR" ]; then
      echo "错误:项目目录不存在: $PROJECT_DIR"
      exit 1
    fi

    # 分析项目结构
    echo "分析项目结构..."
    claude --add-dir "$PROJECT_DIR" \
           -p "分析项目结构、代码质量和潜在问题" \
           --output-format "$OUTPUT_FORMAT" \
           > "project_analysis.$OUTPUT_FORMAT"

    # 生成报告
    echo "生成分析报告..."
    claude -p "根据分析结果生成详细的报告" \
      --input-format "$OUTPUT_FORMAT" \
      --output-format markdown \
      > "project_report.md"

    echo "项目分析完成"
    echo "分析结果: project_analysis.$OUTPUT_FORMAT"
    echo "分析报告: project_report.md"

### 5\. 批量处理脚本

    bash


    #!/bin/bash

    # 批量处理脚本
    # 用法: ./batch_process.sh [文件模式] [处理类型]

    set -e

    # 参数处理
    FILE_PATTERN=${1:-*.py}
    PROCESS_TYPE=${2:-optimize}

    # 定义处理函数
    optimize_files() {
      for file in $FILE_PATTERN; do
        echo "优化文件: $file"
        claude -p "优化 $file 的性能" > "${file%.py}.optimized.py"
      done
    }

    review_files() {
      for file in $FILE_PATTERN; do
        echo "审查文件: $file"
        claude -p "审查 $file 的代码质量" > "${file%.py}.review.md"
      done
    }

    refactor_files() {
      for file in $FILE_PATTERN; do
        echo "重构文件: $file"
        claude -p "重构 $file 的代码结构" > "${file%.py}.refactored.py"
      done
    }

    # 根据处理类型执行处理
    case $PROCESS_TYPE in
      "optimize")
        optimize_files
        ;;
      "review")
        review_files
        ;;
      "refactor")
        refactor_files
        ;;
      *)
        echo "错误:未知处理类型: $PROCESS_TYPE"
        echo "支持的处理类型: optimize, review, refactor"
        exit 1
        ;;
    esac

    echo "批量处理完成"

## 脚本最佳实践

### 1\. 脚本组织


  * **模組化** :將複雜指令碼拆分成多個函式
  * **配置化** :使用配置檔案管理引數
  * **文件化** :為指令碼新增詳細的註釋和文件

#### 示例:模块化脚本

    bash


    #!/bin/bash

    # 导入配置文件
    source config.sh

    # 导入函数库
    source lib/functions.sh

    # 主函数
    main() {
      initialize
      execute_tasks
      cleanup
    }

    # 执行主函数
    main

### 2\. 错误处理
  • 設定錯誤處理 :使用 set -etrap
  • 檢查返回值 :檢查命令的退出碼
  • 提供清晰的錯誤資訊 :為使用者提供有用的錯誤資訊
bash
#### 示例:完善的错误处理

    bash


    #!/bin/bash

    # 设置错误处理
    set -e
    set -u
    set -o pipefail

    # 定义错误处理函数
    error_handler() {
      local exit_code=$1
      local line_number=$2
      echo "错误: 脚本在第 $line_number 行失败,退出码: $exit_code"
      cleanup
      exit $exit_code
    }

    # 设置错误处理
    trap 'error_handler $? $LINENO' ERR

    # 定义清理函数
    cleanup() {
      echo "执行清理操作..."
      rm -f temp_files/*
    }

    # 执行任务
    main

### 3\. 日志记录
  • 記錄執行過程 :記錄指令碼的執行過程
  • 記錄錯誤資訊 :記錄錯誤和警告資訊
  • 記錄效能指標 :記錄執行時間和資源使用情況
bash
#### 示例:日志记录

    bash


    #!/bin/bash

    # 定义日志函数
    log() {
      local level=$1
      shift
      local message="$@"
      local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
      echo "[$timestamp] [$level] $message" >> script.log
    }

    # 使用日志函数
    log INFO "脚本开始执行"
    log INFO "执行任务1"
    claude -p "执行任务1"
    log INFO "任务1完成"
    log INFO "脚本执行完成"

### 4\. 性能优化


  * **並行處理** :使用後臺執行和 wait 提高效率
  * **快取結果** :避免重複執行相同的命令
  * **增量處理** :只處理變化的部分

#### 示例:性能优化

    bash


    #!/bin/bash

    # 并行处理多个文件
    for file in *.py; do
      claude -p "分析 $file" > "${file%.py}.analysis.json" &
    done
    wait

    # 使用缓存
    CACHE_FILE="analysis.cache"
    if [ -f "$CACHE_FILE" ]; then
      log INFO "使用缓存结果"
      cat "$CACHE_FILE"
    else
      claude -p "分析项目" > "$CACHE_FILE"
    fi

## 总结

指令碼編寫是自動化 Claude Code 任務的關鍵技能。透過掌握 Bash 指令碼的基礎知識(變數、函式、條件判斷、迴圈、錯誤處理)和實用指令碼示例,您可以建立強大、可重用的自動化工具。

記住以下要點:

  1. 從簡單開始 :先編寫簡單的指令碼,逐步增加複雜性
  2. 注重實踐 :透過實際專案練習指令碼編寫
  3. 遵循最佳實踐 :使用錯誤處理、日誌記錄和效能最佳化
  4. 持續改進 :不斷最佳化和改進您的指令碼

在接下來的章節中,我們將學習如何將這些指令碼整合到 CI/CD 流程中,以及如何進行批處理操作和實際工作流應用。

基于 MIT 许可发布 | 永久导航