8.2 脚本编写

第 8 章 · 命令组合与集成自动化 · 第2部分:命令参考

在上一节中,我们学习了命令组合的基础知识。在本节中,我们将学习如何将这些命令组合封装成可重用的脚本,以便更高效地自动化各种任务。

脚本编写概述#

脚本是将一系列命令和逻辑组合在一起的可执行文件。使用脚本可以:

  • 提高效率:自动化重复性任务
  • 减少错误:避免手动操作的错误
  • 便于维护:集中管理复杂的逻辑
  • 易于分享:方便与团队成员共享

Bash 脚本基础#

1. 脚本结构#

一个基本的 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:管道中任何命令失败都导致整个管道失败
  • #:注释符号

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=$1MODEL=${2:-sonnet}# 默认值为 sonnetOUTPUT_FORMAT=${3:-json} # 检查参数if[ -z "$PROJECT_DIR"];thenecho"错误:必须指定项目目录"echo"用法: $0 [模型] [输出格式]"exit1fi # 使用参数claude --model "$MODEL"\ --add-dir "$PROJECT_DIR"\ -p "分析项目"\ --output-format "$OUTPUT_FORMAT"

示例:使用命名参数

bash
复制
#!/bin/bash # 定义命名参数whilegetopts"d:m:f:v" opt;docase$optin d)PROJECT_DIR="$OPTARG";; m)MODEL="$OPTARG";; f)OUTPUT_FORMAT="$OPTARG";;v)VERBOSE=true ;;\?)echo"无效选项: -$OPTARG">&2;exit1;;esacdone # 设置默认值PROJECT_DIR=${PROJECT_DIR:-./myproject}MODEL=${MODEL:-sonnet}OUTPUT_FORMAT=${OUTPUT_FORMAT:-json}VERBOSE=${VERBOSE:-false} # 使用参数if["$VERBOSE"=true];thenecho"项目目录: $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(){localfile=$1localmodel=${2:-sonnet} echo"分析文件: $file" claude --model "$model" -p "分析 $file 的代码质量"} # 使用函数analyze_file main.py analyze_file utils.js opus

示例:带返回值的函数

bash
复制
#!/bin/bash # 定义带返回值的函数get_model(){localtask_type=$1 case$task_typein"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"];thenecho"配置文件存在" claude -p "使用配置文件"elseecho"配置文件不存在" claude -p "使用默认配置"fi # 检查命令执行结果if claude -p "检查代码质量";thenecho"代码质量检查通过"elseecho"代码质量检查失败"exit1fi # 多条件判断if[ -f "config.json"]&&[ -f "settings.json"];thenecho"所有配置文件都存在"elif[ -f "config.json"];thenecho"只有 config.json 存在"elseecho"配置文件不存在"fi

示例:case 语句

bash
复制
#!/bin/bash # 使用 case 语句TASK_TYPE=$1 case$TASK_TYPEin"review")echo"执行代码审查" claude -p "审查代码";;"test")echo"执行测试" claude -p "运行测试";;"deploy")echo"执行部署" claude -p "部署应用";; *)echo"未知任务类型: $TASK_TYPE"echo"支持的任务类型: review, test, deploy"exit1;;esac

5. 循环结构#

示例:for 循环

bash
复制
#!/bin/bash # 遍历文件forfilein *.py;doecho"处理文件: $file" claude -p "优化 $file 的性能"done # 遍历数组projects=("frontend""backend""api")forprojectin"${projects[@]}";doecho"处理项目: $project" claude --add-dir "./$project" -p "分析项目"done # 数字循环foriin{1..5};doecho"执行第 $i 次迭代" claude -p "执行任务 $i"done

示例:while 循环

bash
复制
#!/bin/bash # 持续监控文件变化while inotifywait -e modify *.py;doecho"检测到文件变化" claude -p "重新分析代码"done # 读取文件内容whileIFS=read -r line;doecho"处理行: $line" claude -p "处理: $line"done input.txt # 条件循环count=0while[$count -lt 5];doecho"计数: $count" claude -p "执行任务 $count"((count++))done

6. 错误处理#

示例:基本错误处理

bash
复制
#!/bin/bash # 设置错误处理set -e # 检查命令是否成功if! claude -p "生成代码";thenecho"错误:代码生成失败"exit1fi # 使用 trap 捕获错误trap'echo "发生错误,退出码: $?"' ERR claude -p "执行任务1"claude -p "执行任务2"claude -p "执行任务3"

示例:高级错误处理

bash
复制
#!/bin/bash # 定义错误处理函数handle_error(){localexit_code=$1localline_number=$2echo"错误发生在第 $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"];thenecho"错误:目标不存在: $TARGET"exit1fi # 检查是文件还是目录if[ -f "$TARGET"];thenecho"审查文件: $TARGET" claude --model "$MODEL" -p "审查 $TARGET 的代码质量、安全性和性能"elif[ -d "$TARGET"];thenecho"审查目录: $TARGET" claude --model "$MODEL" --add-dir "$TARGET" -p "审查目录中的所有文件"elseecho"错误:不支持的目标类型"exit1fi

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_TYPEin"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"exit1;;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"];thenecho"错误:项目目录不存在: $PROJECT_DIR"exit1fi # 分析项目结构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(){forfilein$FILE_PATTERN;doecho"优化文件: $file" claude -p "优化 $file 的性能">"${file%.py}.optimized.py"done} review_files(){forfilein$FILE_PATTERN;doecho"审查文件: $file" claude -p "审查 $file 的代码质量">"${file%.py}.review.md"done} refactor_files(){forfilein$FILE_PATTERN;doecho"重构文件: $file" claude -p "重构 $file 的代码结构">"${file%.py}.refactored.py"done} # 根据处理类型执行处理case$PROCESS_TYPEin"optimize") optimize_files ;;"review") review_files ;;"refactor") refactor_files ;; *)echo"错误:未知处理类型: $PROCESS_TYPE"echo"支持的处理类型: optimize, review, refactor"exit1;;esac echo"批量处理完成"

脚本最佳实践#

1. 脚本组织#

  • 模块化:将复杂脚本拆分成多个函数
  • 配置化:使用配置文件管理参数
  • 文档化:为脚本添加详细的注释和文档

示例:模块化脚本

bash
复制
#!/bin/bash # 导入配置文件source config.sh # 导入函数库source lib/functions.sh # 主函数main(){ initialize execute_tasks cleanup } # 执行主函数main

2. 错误处理#

  • 设置错误处理:使用 set -e 和 trap
  • 检查返回值:检查命令的退出码
  • 提供清晰的错误信息:为用户提供有用的错误信息

示例:完善的错误处理

bash
复制
#!/bin/bash # 设置错误处理set -e set -u set -o pipefail # 定义错误处理函数error_handler(){localexit_code=$1localline_number=$2echo"错误: 脚本在第 $line_number 行失败,退出码: $exit_code" cleanup exit$exit_code} # 设置错误处理trap'error_handler $? $LINENO' ERR # 定义清理函数cleanup(){echo"执行清理操作..."rm -f temp_files/* } # 执行任务main

3. 日志记录#

  • 记录执行过程:记录脚本的执行过程
  • 记录错误信息:记录错误和警告信息
  • 记录性能指标:记录执行时间和资源使用情况

示例:日志记录

bash
复制
#!/bin/bash # 定义日志函数log(){locallevel=$1shiftlocalmessage="$@"localtimestamp=$(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 # 并行处理多个文件forfilein *.py;do claude -p "分析 $file">"${file%.py}.analysis.json"&donewait # 使用缓存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 流程中,以及如何进行批处理操作和实际工作流应用。