linux-sre-handbook

04-脚本调试技巧

基础调试开关

#!/bin/bash
set -e              # 任何命令失败立即退出
set -u              # 使用未定义变量时报错
set -o pipefail     # 管道中任一命令失败则整个管道失败
set -x              # 打印每条执行的命令

# 推荐组合
set -euo pipefail

调试方法

1. 分段调试(set -x)

set -x                  # 开启追踪
# ... 需要调试的代码 ...
set +x                  # 关闭追踪

2. 临时忽略错误

set +e              # 临时允许失败
risky_command || true
set -e              # 恢复严格模式

3. trap 捕获错误

#!/bin/bash
set -euo pipefail

on_error() {
    echo "ERROR at line $1"
    exit 1
}
trap 'on_error $LINENO' ERR

# 清理资源
cleanup() {
    rm -f /tmp/lockfile
}
trap cleanup EXIT

4. 手动日志

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
}
log "Starting backup..."
log "ERROR: disk full"

ShellCheck 静态检查

shellcheck script.sh     # 发现潜在问题
# 常见警告:
# SC2086: 变量未加引号
# SC2164: cd 未检查返回值
# SC2046: 命令替换未加引号

常见脚本陷阱

陷阱 正确做法
[ $var == "value" ] [[ $var == "value" ]][ "$var" = "value" ]
cd /some/dir 后操作 cd /some/dir || exit 1
rm -rf $DIR/* 先检查 $DIR 非空:[[ -n "$DIR" ]]
cat file | grep grep pattern file(无谓 cat)
未处理文件名空格 find ... -print0 \| xargs -0

性能分析与基准测试

# 脚本耗时分析
time script.sh

# 更详细的性能分析
PS4='+ $(date "+%s.%N")\011 ' bash -x script.sh

# 特定命令耗时
start=$(date +%s%N)
# ... 操作 ...
end=$(date +%s%N)
echo "耗时: $(((end-start)/1000000))ms"

延伸阅读