aboutsummaryrefslogtreecommitdiffstats
path: root/.agents/skills/bug-detective/examples/debugging-workflow.sh
diff options
context:
space:
mode:
Diffstat (limited to '.agents/skills/bug-detective/examples/debugging-workflow.sh')
-rwxr-xr-x.agents/skills/bug-detective/examples/debugging-workflow.sh400
1 files changed, 400 insertions, 0 deletions
diff --git a/.agents/skills/bug-detective/examples/debugging-workflow.sh b/.agents/skills/bug-detective/examples/debugging-workflow.sh
new file mode 100755
index 0000000..1ff74a5
--- /dev/null
+++ b/.agents/skills/bug-detective/examples/debugging-workflow.sh
@@ -0,0 +1,400 @@
+#!/bin/bash
+#
+# Shell 脚本调试流程示例
+# 展示常见的 Bash 脚本错误和调试方法
+#
+
+# ============================================
+# 调试设置
+# ============================================
+
+# 取消注释以启用调试模式
+# set -x # 打印每个命令
+# set -e # 错误时退出
+# set -u # 未定义变量报错
+# set -o pipefail # 管道中任何命令失败则失败
+
+# 或组合使用
+# set -xeuo pipefail # 严格模式
+
+
+# ============================================
+# 错误处理函数
+# ============================================
+
+# 错误退出函数
+die() {
+ local message="$1"
+ local exit_code="${2:-1}"
+ echo "Error: $message" >&2
+ exit "$exit_code"
+}
+
+# 记录函数
+log() {
+ local level="$1"
+ shift
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" >&2
+}
+
+log_info() { log "INFO" "$@"; }
+log_warn() { log "WARN" "$@"; }
+log_error() { log "ERROR" "$@"; }
+
+
+# ============================================
+# 问题 1:未引用的变量
+# ============================================
+
+# 错误示例:变量未引用
+demo_unquoted_variable() {
+ echo "=== 问题 1:未引用的变量 ==="
+
+ local name="John Doe"
+
+ # 错误:变量未引用,空值会导致语法错误
+ # if [ $name = "John Doe" ]; then
+ # echo "Match"
+ # fi
+
+ # 正确:始终引用变量
+ if [ "$name" = "John Doe" ]; then
+ log_info "变量匹配: $name"
+ fi
+}
+
+
+# ============================================
+# 问题 2:命令失败继续执行
+# ============================================
+
+demo_command_failure() {
+ echo "=== 问题 2:命令失败继续执行 ==="
+
+ # 错误:cd 失败后继续执行
+ # cd /nonexistent_directory
+ # rm -rf file.txt # 会删除当前目录的文件!
+
+ # 正确:检查命令是否成功
+ cd /tmp || die "无法切换到 /tmp 目录"
+ log_info "成功切换到目录: $(pwd)"
+
+ cd - > /dev/null || true
+}
+
+
+# ============================================
+# 问题 3:循环中的变量作用域(管道问题)
+# ============================================
+
+demo_pipeline_scope() {
+ echo "=== 问题 3:管道中的变量作用域 ==="
+
+ local count=0
+
+ # 错误:管道创建子 shell,外部变量不改变
+ # echo -e "1\n2\n3" | while read line; do
+ # count=$((count + 1))
+ # done
+ # echo "Count: $count" # 输出 0
+
+ # 正确:使用重定向
+ while read line; do
+ count=$((count + 1))
+ done < <(echo -e "1\n2\n3")
+ log_info "计数结果: $count"
+}
+
+
+# ============================================
+# 问题 4:数组操作
+# ============================================
+
+demo_array_operations() {
+ echo "=== 问题 4:数组操作 ==="
+
+ local fruits=("apple" "banana" "cherry")
+
+ # 错误的数组访问
+ # echo $fruits[1] # 输出 apple[1]
+
+ # 正确的数组访问
+ log_info "第一个元素: ${fruits[0]}"
+ log_info "第二个元素: ${fruits[1]}"
+ log_info "所有元素: ${fruits[@]}"
+ log_info "数组长度: ${#fruits[@]}"
+
+ # 遍历数组
+ for fruit in "${fruits[@]}"; do
+ log_info "水果: $fruit"
+ done
+}
+
+
+# ============================================
+# 问题 5:字符串比较
+# ============================================
+
+demo_string_comparison() {
+ echo "=== 问题 5:字符串比较 ==="
+
+ local name="John"
+
+ # 错误:数字比较使用 =
+ # if [ $age = 18 ]; then
+
+ # 正确:字符串比较
+ if [[ "$name" == "John" ]]; then
+ log_info "字符串匹配"
+ fi
+
+ # 正确:数字比较
+ local age=18
+ if [ "$age" -eq 18 ]; then
+ log_info "数字匹配"
+ fi
+}
+
+
+# ============================================
+# 问题 6:算术运算
+# ============================================
+
+demo_arithmetic() {
+ echo "=== 问题 6:算术运算 ==="
+
+ local a=10
+ local b=5
+
+ # 错误:使用 let 或 $(())
+ # result = a + b # 这是命令调用
+
+ # 正确的算术运算
+ local result=$((a + b))
+ log_info "加法: $a + $b = $result"
+
+ result=$((a - b))
+ log_info "减法: $a - $b = $result"
+
+ result=$((a * b))
+ log_info "乘法: $a * $b = $result"
+
+ result=$((a / b))
+ log_info "除法: $a / $b = $result"
+
+ # 使用 let
+ let result=a+b
+ log_info "let 加法: $result"
+}
+
+
+# ============================================
+# 参数验证
+# ============================================
+
+validate_arguments() {
+ echo "=== 参数验证 ==="
+
+ # 检查参数数量
+ if [ $# -lt 2 ]; then
+ die "用法: $0 <文件> <目录>" 2
+ fi
+
+ local file="$1"
+ local dir="$2"
+
+ # 检查文件存在
+ if [ ! -f "$file" ]; then
+ die "文件不存在: $file" 3
+ fi
+
+ # 检查目录存在
+ if [ ! -d "$dir" ]; then
+ die "目录不存在: $dir" 4
+ fi
+
+ log_info "参数验证通过"
+ log_info "文件: $file"
+ log_info "目录: $dir"
+}
+
+
+# ============================================
+# 使用 trap 进行清理
+# ============================================
+
+demo_trap() {
+ echo "=== 使用 trap 进行清理 ==="
+
+ # 设置清理函数
+ cleanup() {
+ log_info "执行清理操作..."
+ # 这里可以执行清理操作
+ }
+
+ # 捕获退出信号
+ trap cleanup EXIT
+
+ # 捕获错误信号
+ trap 'log_error "发生错误,行号: $LINENO"' ERR
+
+ # 捕获中断信号
+ trap 'log_warn "脚本被中断"; cleanup; exit 130' INT
+
+ log_info "执行一些操作..."
+ # 模拟操作
+ sleep 1
+}
+
+
+# ============================================
+# 调试技巧示例
+# ============================================
+
+demo_debugging() {
+ echo "=== 调试技巧 ==="
+
+ # 1. 使用 echo 调试
+ local value="test"
+ echo "[DEBUG] value = $value" >&2
+
+ # 2. 使用 printf 格式化输出
+ printf "[DEBUG] Count: %d, Name: %s\n" 42 "John" >&2
+
+ # 3. 检查变量是否设置
+ if [ -z "${unset_var+x}" ]; then
+ log_warn "变量 unset_var 未设置"
+ fi
+
+ # 4. 显示调用栈
+ log_info "调用栈:"
+ local i=0
+ while caller $i; do
+ ((i++))
+ done 2>/dev/null || true
+}
+
+
+# ============================================
+# 文件操作错误处理
+# ============================================
+
+demo_file_operations() {
+ echo "=== 文件操作错误处理 ==="
+
+ local tmpfile=$(mktemp) || die "无法创建临时文件"
+
+ # 确保文件被删除
+ trap "rm -f '$tmpfile'" EXIT
+
+ # 写入文件
+ echo "Test content" > "$tmpfile" || die "无法写入文件: $tmpfile"
+
+ # 读取文件
+ local content
+ content=$(cat "$tmpfile") || die "无法读取文件: $tmpfile"
+
+ log_info "文件内容: $content"
+
+ # trap 会自动清理
+}
+
+
+# ============================================
+# 带重试的操作
+# ============================================
+
+demo_retry() {
+ echo "=== 带重试的操作 ==="
+
+ local max_attempts=3
+ local attempt=1
+
+ while [ $attempt -le $max_attempts ]; do
+ log_info "尝试 $attempt/$max_attempts..."
+
+ # 模拟可能失败的操作
+ if [ $attempt -eq 2 ]; then
+ log_info "成功!"
+ return 0
+ fi
+
+ log_warn "失败,重试..."
+ ((attempt++))
+ sleep 1
+ done
+
+ log_error "所有尝试都失败了"
+ return 1
+}
+
+
+# ============================================
+# 检查依赖
+# ============================================
+
+check_dependencies() {
+ echo "=== 检查依赖 ==="
+
+ local required_commands=("curl" "jq" "git")
+
+ for cmd in "${required_commands[@]}"; do
+ if ! command -v "$cmd" &> /dev/null; then
+ log_error "缺少依赖: $cmd"
+ return 1
+ fi
+ log_info "✓ $cmd 可用"
+ done
+
+ log_info "所有依赖都已满足"
+}
+
+
+# ============================================
+# 主函数
+# ============================================
+
+main() {
+ echo "============================================"
+ echo "Shell 脚本调试示例"
+ echo "============================================"
+
+ # 运行各个示例
+ demo_unquoted_variable
+ echo ""
+
+ demo_command_failure
+ echo ""
+
+ demo_pipeline_scope
+ echo ""
+
+ demo_array_operations
+ echo ""
+
+ demo_string_comparison
+ echo ""
+
+ demo_arithmetic
+ echo ""
+
+ demo_trap
+ echo ""
+
+ demo_debugging
+ echo ""
+
+ demo_file_operations
+ echo ""
+
+ demo_retry
+ echo ""
+
+ check_dependencies
+ echo ""
+
+ log_info "所有示例执行完成"
+}
+
+# 运行主函数
+main "$@"