mcpField
B
bash-pro

bash-pro

github.com/rmyndharis开发1.9k121 次安装2 周前更新
代码仓库

关于 bash-pro

面向 Bash 脚本编写、审查和加固的开发技能,涵盖安全参数处理、错误管理、可移植性和测试。适用于自动化、CI/CD 与运维脚本工作。

主要功能

  1. 01严格模式与错误处理
  2. 02安全参数解析和输入校验
  3. 03稳健文件与进程操作
  4. 04Bats 测试与 ShellCheck 静态分析
  5. 05跨平台兼容性指导
  6. 06日志、文档与 CI/CD 实践

适用场景

  1. 01编写自动化 Bash 脚本
  2. 02加固部署或运维脚本
  3. 03审查脚本输入与文件操作安全
  4. 04为脚本添加测试和 CI 检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rmyndharis/antigravity-skills --skill bash-pro

安装后在 Claude Code 中输入/bash-pro确认已加载。

详细介绍

何时使用此技能

  • 为自动化、CI/CD 或运维编写或审查 Bash 脚本
  • 加固 Shell 脚本以提升安全性和可移植性

何时不要使用此技能

  • 你需要仅限 POSIX 的 Shell,不使用 Bash 特性
  • 任务需要更高级的语言来处理复杂逻辑
  • 你需要 Windows 原生脚本(PowerShell)

说明

  1. 定义脚本的输入、输出和失败模式。
  2. 应用严格模式和安全参数解析。
  3. 使用防御性模式实现核心逻辑。
  4. 使用 Bats 和 ShellCheck 添加测试和代码检查。

安全性

  • 将输入视为不可信;避免 eval 和不安全的通配符展开。
  • 在执行破坏性操作前优先使用试运行模式。

重点领域

  • 具有严格错误处理的防御性编程
  • POSIX 合规性和跨平台可移植性
  • 安全的参数解析和输入验证
  • 稳健的文件操作和临时资源管理
  • 进程编排和管道安全
  • 生产级日志记录和错误报告
  • 使用 Bats 框架进行全面测试
  • 使用 ShellCheck 进行静态分析,使用 shfmt 进行格式化
  • 现代 Bash 5.x 特性和最佳实践
  • CI/CD 集成和自动化工作流

方法

  • 始终使用严格模式 set -Eeuo pipefail 和适当的错误捕获
  • 为所有变量展开添加引号,以防止单词拆分和通配符展开问题
  • 优先使用数组和正确的迭代,而非 for f in $(ls) 等不安全模式
  • 使用 [[ ]] 进行 Bash 条件判断,为 POSIX 合规性回退到 [ ]
  • 使用 getopts 和用法函数实现全面的参数解析
  • 使用 mktemp 和清理陷阱安全地创建临时文件和目录
  • 优先使用 printf 而非 echo,以获得可预测的输出格式
  • 使用命令替换 $() 而非反引号,以提高可读性
  • 实现带时间戳和可配置详细程度的结构化日志记录
  • 将脚本设计为幂等并支持试运行模式
  • 在 Bash 4.4+ 中使用 shopt -s inherit_errexit 以实现更好的错误传播
  • 使用 IFS=$'\n\t' 防止对空格进行不必要的单词拆分
  • 使用 : "${VAR:?message}" 验证必需环境变量的输入
  • 以 -- 结束选项解析,并使用 rm -rf -- "$dir" 进行安全操作
  • 通过 set -x 选择性启用 --trace 模式以进行详细调试
  • 使用 xargs -0 配合 NUL 边界进行安全的子进程编排
  • 使用 readarray/mapfile 从命令输出安全填充数组
  • 实现稳健的脚本目录检测:SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
  • 使用 NUL 安全模式:find -print0 | while IFS= read -r -d '' file; do ...; done

兼容性与可移植性

  • 使用 #!/usr/bin/env bash shebang 以实现跨系统可移植性
  • 在脚本开头检查 Bash 版本:(( BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 4 )) 以使用 Bash 4.4+ 特性
  • 验证所需外部命令存在:command -v jq &>/dev/null || exit 1
  • 检测平台差异:case "$(uname -s)" in Linux*) ... ;; Darwin*) ... ;; esac
  • 处理 GNU 与 BSD 工具的差异(例如 sed -i 与 sed -i '')
  • 在所有目标平台(Linux、macOS、BSD 变体)上测试脚本
  • 在脚本头部注释中记录最低版本要求
  • 为平台特定功能提供回退实现
  • 尽可能使用 Bash 内置特性而非外部命令,以提高可移植性
  • 在需要 POSIX 合规性时避免使用 Bash 特有语法,使用 Bash 特定特性时加以说明

可读性与可维护性

  • 在脚本中为清晰起见使用长格式选项:用 --verbose 而不是 -v
  • 采用一致的命名:函数/变量使用 snake_case,常量使用 UPPER_CASE
  • 使用注释块添加章节标题,以组织相关函数
  • 将函数保持在 50 行以内;将较大的函数重构为更小的组件
  • 将相关函数分组在一起,并配上描述性的章节标题
  • 使用能说明用途的描述性函数名:用 validate_input_file 而不是 check_file
  • 为非显而易见的逻辑添加行内注释,避免陈述显而易见的内容
  • 保持一致的缩进(2 或 4 个空格,切勿将制表符与空格混用)
  • 为保持一致,将左花括号放在同一行:function_name() {
  • 使用空行分隔函数内的逻辑块
  • 在头部注释中记录函数参数和返回值
  • 将魔法数字和字符串提取为脚本顶部的具名常量

安全与安全模式

  • 使用 readonly 声明常量,以防止意外修改
  • 为所有函数变量使用 local 关键字,以避免污染全局作用域
  • 为外部命令实现 timeout:timeout 30s curl ... 可防止挂起
  • 在操作前验证文件权限:[[ -r "$file" ]] || exit 1
  • 尽可能使用进程替换 <(command) 而不是临时文件
  • 在用于命令或文件操作之前,清理用户输入
  • 使用模式匹配验证数字输入:[[ $num =~ ^[0-9]+$ ]]
  • 切勿对用户输入使用 eval;使用数组进行动态命令构建
  • 为敏感操作设置限制性的 umask:(umask 077; touch "$secure_file")
  • 记录与安全相关的操作(身份验证、权限变更、文件访问)
  • 使用 -- 将选项与参数分隔开:rm -rf -- "$user_input"
  • 在使用环境变量之前验证它们:: "${REQUIRED_VAR:?not set}"
  • 显式检查所有安全关键操作的退出码
  • 使用 trap 确保即使异常退出也能执行清理

性能优化

  • 避免在循环中使用子 shell;使用 while read 而不是 for i in $(cat file)
  • 优先使用 Bash 内建命令而非外部命令:用 [[ ]] 而不是 test,用 ${var//pattern/replacement} 而不是 sed
  • 批量操作而不是重复的单个操作(例如,一个带多个表达式的 sed)
  • 使用 mapfile/readarray 从命令输出高效填充数组
  • 避免重复的命令替换;将结果一次性存入变量
  • 使用算术展开 $(( )) 而不是 expr 进行计算
  • 对于格式化输出,优先使用 printf 而不是 echo(更快且更可靠)
  • 使用关联数组进行查找,而不是重复 grep
  • 对于大文件,逐行处理而不是将整个文件加载到内存中
  • 当操作相互独立时,使用 xargs -P 进行并行处理

文档标准

  • 实现 --help 和 -h 标志,显示用法、选项和示例
  • 提供 --version 标志,显示脚本版本和版权信息
  • 在帮助输出中包含常见用例的使用示例
  • 记录所有命令行选项及其用途说明
  • 在用法消息中清晰列出必需与可选参数
  • 记录退出码:0 表示成功,1 表示一般错误,特定失败使用特定代码
  • 包含列出所需命令及版本的前提条件章节
  • 添加头部注释块,包含脚本用途、作者和修改日期
  • 记录脚本使用或需要的环境变量
  • 在帮助中为常见问题提供故障排除章节
  • 使用 shdoc 从特殊注释格式生成文档
  • 使用 shellman 创建 man 手册页以便系统集成
  • 为复杂脚本包含使用 Mermaid 或 GraphViz 绘制的架构图

现代 Bash 特性(5.x)

  • Bash 5.0:关联数组改进,${var@U} 大写转换,${var@L} 小写
  • Bash 5.1:增强的 ${parameter@operator} 转换,用于兼容性的 compat shopt 选项
  • Bash 5.2:varredir_close 选项,改进的 exec 错误处理,EPOCHREALTIME 微秒精度
  • 在使用现代特性前检查版本:[[ ${BASH_VERSINFO[0]} -ge 5 && ${BASH_VERSINFO[1]} -ge 2 ]]
  • 使用 ${parameter@Q} 输出 shell 引用的结果(Bash 4.4+)
  • 使用 ${parameter@E} 展开转义序列(Bash 4.4+)
  • 使用 ${parameter@P} 展开提示词(Bash 4.4+)
  • 使用 ${parameter@A} 输出赋值格式(Bash 4.4+)
  • 使用 wait -n 等待任意后台任务(Bash 4.3+)
  • 使用 mapfile -d delim 自定义分隔符(Bash 4.4+)

CI/CD 集成

  • GitHub Actions:使用 shellcheck-problem-matchers 实现内联注释
  • Pre-commit 钩子:使用 shellcheck、shfmt、checkbashisms 配置 .pre-commit-config.yaml
  • 矩阵测试:在 Linux 和 macOS 上跨 Bash 4.4、5.0、5.1、5.2 进行测试
  • 容器测试:使用官方 bash:5.2 Docker 镜像进行可复现的测试
  • CodeQL:启用 shell 脚本扫描以发现安全漏洞
  • Actionlint:验证使用 shell 脚本的 GitHub Actions 工作流文件
  • 自动发布:自动打版本标签并生成变更日志
  • 覆盖率报告:跟踪测试覆盖率并在出现回退时失败
  • 示例工作流:shellcheck *.sh && shfmt -d *.sh && bats test/

安全扫描与加固

  • SAST:集成 Semgrep 并配置针对 shell 特定漏洞的自定义规则
  • 密钥检测:使用 gitleaks 或 trufflehog 防止凭据泄露
  • 供应链:验证所引用外部脚本的校验和
  • 沙箱化:在具有受限权限的容器中运行不受信任的脚本
  • SBOM:记录依赖项和外部工具以满足合规要求
  • 安全静态检查:启用面向安全的规则使用 ShellCheck
  • 权限分析:审计脚本中不必要的 root/sudo 需求
  • 输入清理:根据允许列表验证所有外部输入
  • 审计日志:将所有与安全相关的操作记录到 syslog
  • 容器安全:扫描脚本执行环境中的漏洞

可观测性与日志

  • 结构化日志:输出 JSON 以供日志聚合系统使用
  • 日志级别:实现 DEBUG、INFO、WARN、ERROR 并支持可配置的详细程度
  • Syslog 集成:使用 logger 命令集成系统日志
  • 分布式追踪:添加 trace ID 以关联多脚本工作流
  • 指标导出:输出 Prometheus 格式指标以供监控
  • 错误上下文:在错误日志中包含堆栈跟踪、环境信息
  • 日志轮转:为长时间运行的脚本配置日志文件轮转
  • 性能指标:跟踪执行时间、资源使用、外部调用延迟
  • 示例:log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }

质量检查清单

  • 脚本以最少的抑制通过 ShellCheck 静态分析
  • 代码使用 shfmt 以标准选项保持一致的格式
  • 使用 Bats 实现全面的测试覆盖,包括边界情况
  • 所有变量展开都正确加引号
  • 错误处理覆盖所有失败模式并提供有意义的错误信息
  • 临时资源通过 EXIT trap 正确清理
  • 脚本支持 --help 并提供清晰的用法信息
  • 输入验证可防止注入攻击并处理边界情况
  • 脚本可跨目标平台移植(Linux、macOS)
  • 性能足以应对预期的工作负载和数据规模

输出

  • 生产级 Bash 脚本,遵循防御性编程实践
  • 使用 bats-core 或 shellspec 并结合 TAP 输出的全面测试套件
  • 用于自动化测试的 CI/CD 流水线配置(GitHub Actions、GitLab CI)
  • 使用 shdoc 生成的文档以及使用 shellman 生成的 man 手册页
  • 具有可复用库函数和依赖管理的结构化项目布局
  • 静态分析配置文件(.shellcheckrc、.shfmt.toml、.editorconfig)
  • 针对关键工作流的性能基准测试和性能分析报告
  • 包含 SAST、密钥扫描和漏洞报告的安全审查
  • 具有跟踪模式、结构化日志和可观测性的调试实用工具
  • 针对 Bash 3→5 升级和遗留系统现代化的迁移指南
  • 包分发配置(Homebrew formula、deb/rpm 规范)
  • 用于可复现执行环境的容器镜像

必备工具

静态分析与格式化
  • ShellCheck:静态分析器,配置 enable=all 和 external-sources=true
  • shfmt:Shell 脚本格式化工具,使用标准配置(-i 2 -ci -bn -sr -kp)
  • checkbashisms:检测 bash 特有的构造,用于可移植性分析
  • Semgrep:SAST,提供针对 shell 特有安全问题的自定义规则
  • CodeQL:GitHub 针对 shell 脚本的安全扫描
测试框架
  • bats-core:Bats 的维护分支,具有现代特性和活跃开发
  • shellspec:BDD 风格的测试框架,具有丰富的断言和 mocking 功能
  • shunit2:针对 shell 脚本的 xUnit 风格测试框架
  • bashing:具有 mocking 支持和测试隔离的测试框架
现代开发工具
  • bashly:用于构建命令行应用的 CLI 框架生成器
  • basher:用于依赖管理的 Bash 包管理器
  • bpkg:具有类似 npm 接口的替代 bash 包管理器
  • shdoc:从 shell 脚本注释生成 markdown 文档
  • shellman:从 shell 脚本生成 man 手册页
CI/CD 与自动化
  • pre-commit:多语言 pre-commit 钩子框架
  • actionlint:GitHub Actions 工作流 linter
  • gitleaks:密钥扫描,防止凭据泄露
  • Makefile:用于 lint、format、test 和 release 工作流的自动化

应避免的常见陷阱

  • for f in $(ls ...) 会导致分词/通配符错误(应使用 find -print0 | while IFS= read -r -d '' f; do ...; done)
  • 未加引号的变量展开会导致意外行为
  • 在复杂流程中依赖 set -e 而没有适当的错误捕获
  • 使用 echo 输出数据(优先使用 printf 以确保可靠性)
  • 缺少针对临时文件和目录的清理 trap
  • 不安全的数组填充(使用 readarray/mapfile 而不是命令替换)
  • 忽略二进制安全的文件处理(文件名始终考虑 NUL 分隔符)

依赖管理

  • 包管理器:使用 basher 或 bpkg 安装 shell 脚本依赖
  • Vendoring:将依赖复制到项目中以实现可复现构建
  • 锁文件:记录所用依赖的确切版本
  • 校验和验证:验证所引入外部脚本的完整性
  • 版本固定:将依赖锁定到特定版本,以防止破坏性变更
  • 依赖隔离:为不同的依赖集使用单独的目录
  • 更新自动化:使用 Dependabot 或 Renovate 自动化依赖更新
  • 安全扫描:扫描依赖中的已知漏洞
  • 示例:basher install username/repo@version 或 bpkg install username/repo -g

高级技巧

  • 错误上下文:使用 trap 'echo "Error at line $LINENO: exit $?" >&2' ERR 进行调试
  • 安全处理临时文件:trap 'rm -rf "$tmpdir"' EXIT; tmpdir=$(mktemp -d)
  • 版本检查:使用现代功能前,先检查 (( BASH_VERSINFO[0] >= 5 ))
  • 二进制安全数组:readarray -d '' files < <(find . -print0)
  • 函数返回值:使用 declare -g result 从函数返回复杂数据
  • 关联数组:使用 declare -A config=([host]="localhost" [port]="8080") 表示复杂数据结构
  • 参数展开:${filename%.sh} 移除扩展名,${path##*/} 获取基本名称,${text//old/new} 替换所有匹配项
  • 信号处理:使用 trap cleanup_function SIGHUP SIGINT SIGTERM 实现优雅关闭
  • 命令分组:{ cmd1; cmd2; } > output.log 共享重定向,( cd dir && cmd ) 使用子 shell 实现隔离
  • 协程:coproc proc { cmd; }; echo "data" >&"${proc[1]}"; read -u "${proc[0]}" result 用于双向管道
  • Here 文档:cat <<-'EOF' 中的 - 会移除前导制表符;引号可阻止展开
  • 进程管理:使用 wait $pid 等待后台任务,使用 jobs -p 列出后台进程 ID
  • 条件执行:cmd1 && cmd2 仅当 cmd1 成功时才运行 cmd2,cmd1 || cmd2 在 cmd1 失败时运行 cmd2
  • 花括号展开:touch file{1..10}.txt 可高效创建多个文件
  • 名称引用变量:declare -n ref=varname 创建对另一个变量的引用(Bash 4.3+)
  • 改进错误捕获:使用 set -Eeuo pipefail; shopt -s inherit_errexit 实现全面的错误处理
  • 并行执行:使用 xargs -P $(nproc) -n 1 command,根据 CPU 核心数并行处理
  • 结构化输出:使用 jq -n --arg key "$value" '{key: $key}' 生成 JSON
  • 性能分析:使用 time -v 查看详细资源使用情况,或使用 TIMEFORMAT 自定义计时

参考资料与延伸阅读

风格指南与最佳实践
工具与框架
  • ShellCheck - 静态分析工具,附带详尽的 Wiki 文档
  • shfmt - Shell 脚本格式化工具,附带详细的标志说明
  • bats-core - 持续维护的 Bash 测试框架
  • shellspec - 面向 shell 脚本的 BDD 风格测试框架
  • bashly - 现代 Bash CLI 框架生成器
  • shdoc - Shell 脚本文档生成器
安全与高级主题

评论

支持 Markdown