agents24 项目 bash-pro 专家指南:生产级防御式 Bash 脚本的完整工程实践
导读:
bash-pro是 agents24 多 harness 智能体插件市场中位于plugins/shell-scripting/agents/bash-pro.md的专家型子代理,专注生产级防御式 Bash 编程。本文以其主体定义为核心,结合仓库内配套技能(bash-defensive-patterns、bats-testing-patterns、shellcheck-configuration)与 POSIX 对照文档,系统讲解严格模式、安全参数解析、临时资源管理、Bats 测试、ShellCheck 静态分析以及 CI/CD 集成。读完你将得到一套可直接复用的"写安全、可移植、可测试 Shell 脚本"的工程化方法论。
一、bash-pro 在 agents24 项目中的定位
agents24(仓库根目录 AGENTS.md)是一个多 harness 的 agentic 插件市场:94 个插件、202 个 agent、183 个 skill,以 Markdown 为单一事实源,可被 Claude Code、Codex CLI、Cursor、OpenCode 与 Google Antigravity CLI 原生消费。其中 plugins/shell-scripting/ 插件聚焦 Shell 编程,包含两个 agent:
- bash-pro:面向 Bash 的防御式编程专家,
model: sonnet,适用于生产自动化、CI/CD 管道与系统工具; - posix-shell-pro:面向严格 POSIX sh 的可移植性专家(dash/ash/sh/bash --posix),两者互为对照。
bash-pro 的能力边界(来自其 frontmatter 描述)可归纳为:安全、可移植、可测试的 Shell 脚本。它给出的质量检查清单(Quality Checklist)事实上定义了"生产级脚本"的最低验收标准:通过 ShellCheck、shfmt 统一格式、Bats 全覆盖、所有变量展开带引号、EXIT trap 清理临时资源、支持 --help、输入校验防注入、跨 Linux/macOS 可移植。
二、防御式编程:严格模式与错误处理
2.1 严格模式:set -Eeuo pipefail
bash-pro 的第一条原则是每个脚本以严格模式开场。配套技能 bash-defensive-patterns 将其细化为:
#!/usr/bin/env bash
set -Eeuo pipefail # 退出于错误、未定义变量与管道失败
各标志的真实语义:
| 标志 | 含义 | 说明 |
|---|---|---|
-E |
继承 ERR trap | 让 trap ... ERR 在函数内部也能触发 |
-e |
出错即退出 | 任何命令返回非零立即退出 |
-u |
未定义变量报错 | 引用未定义变量即退出,杜绝拼写错误 |
-o pipefail |
管道失败传播 | 管道中任一命令失败,整条管道返回失败 |
shopt -s inherit_errexit |
继承 errexit | Bash 4.4+ 中让命令替换内的错误也能正确传播 |
2.2 错误陷阱与清理
严格模式不是万能的,复杂流程仍需显式 trap。文档给出的标准组合:
trap 'echo "Error on line $LINENO"' ERR
trap 'echo "Cleaning up..."; rm -rf -- "$TMPDIR"' EXIT
TMPDIR=$(mktemp -d)
高级错误上下文(来自 bash-pro 的 Advanced Techniques)则是 trap 'echo "Error at line $LINENO: exit $?" >&2' ERR,配合 set -Eeuo pipefail; shopt -s inherit_errexit 形成完整错误处理链。POSIX 对照场景(见 posix-shell-pro)则用 trap - EXIT 在成功路径撤销 EXIT trap,避免误报。
2.3 变量安全与引号纪律
bash-pro 反复强调"引用所有变量展开",配套技能给出了正反对照:
# 错误 - 不安全(分词 + 通配符展开)
cp $source $dest
# 正确 - 安全
cp "$source" "$dest"
# 必填环境变量校验:未设置即以错误消息退出
: "${REQUIRED_VAR:?REQUIRED_VAR is not set}"
此外还有 IFS=$'\n\t' 防止空格分词、用 ${var:-default} 提供默认值、${filename%.sh} 等参数展开完成字符串处理。这些细节在 bash-defensive-patterns 中有成体系的工作示例。
三、Safe Argument Parsing:健壮的命令行解析
bash-pro 明确要求用 getopts 与 usage 函数实现参数解析,用 -- 终止选项解析,并用 rm -rf -- "$dir" 保证以 - 开头的路径不被误当作选项。配套技能给出了完整的 while+case 解析模板(details.md):
while [[ $# -gt 0 ]]; do
case "$1" in
-v|--verbose) VERBOSE=true; shift ;;
-d|--dry-run) DRY_RUN=true; shift ;;
-o|--output) OUTPUT_FILE="$2"; shift 2 ;;
-j|--jobs) THREADS="$2"; shift 2 ;;
-h|--help) usage 0 ;;
--) shift; break ;;
*) echo "ERROR: Unknown option: $1" >&2; usage 1 ;;
esac
done
[[ -n "$OUTPUT_FILE" ]] || { echo "ERROR: -o/--output is required" >&2; usage 1; }
同时,bash-pro 强调命名参数模式(--input=* 用 ${1#*=} 剥离前缀)、数字校验([[ $num =~ ^[0-9]+$ ]])以及绝不 eval 用户输入,动态命令一律用数组构造。POSIX 场景下则退化为 while+case(无长选项支持),且只提供 -h。
四、临时资源管理与 NUL 安全文件操作
4.1 mktemp + EXIT trap
trap 'rm -rf -- "$TMPDIR"' EXIT
TMPDIR=$(mktemp -d) || { echo "ERROR: Failed to create temp directory" >&2; exit 1; }
trap 保证无论正常退出还是异常中断都会清理,避免残留临时文件。安全敏感操作还可配合 (umask 077; touch "$secure_file") 收紧权限。
4.2 脚本目录探测与 NUL 安全迭代
bash-pro 给出的两个高频模式:
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
以及处理任意文件名(含空格、换行)的 NUL 安全循环:
find "$input_dir" -type f -print0 | while IFS= read -r -d '' file; do
echo "Processing: $file"
done
配套技能还补充了原子写入(写临时文件再 mv 重命名)与 safe_move/safe_rmdir 等防覆盖封装,这些都是生产脚本避免数据丢失的关键手法。
五、安全与安全审计模式
bash-pro 将安全视为一等公民,核心清单包括:
readonly声明常量,local隔离函数变量;- 外部命令加
timeout 30s curl ...防止挂起; - 操作前校验权限:
[[ -r "$file" ]] || exit 1; - 优先进程替换
<(command)而非临时文件; --隔离选项与参数;command -v jq &>/dev/null || exit 1校验依赖;- 对鉴权、提权、文件访问等安全相关操作留审计日志。
在安全扫描与加固层面,文档给出了完整的供应链防线:SAST(Semgrep 自定义 Shell 规则)、密钥检测(gitleaks/trufflehog)、外部脚本校验和核验、容器沙箱运行不可信脚本、SBOM 依赖清单、ShellCheck 安全规则、sudo/root 特权审计、syslog 审计日志。
六、性能优化:避免子 shell、善用内建命令
bash-pro 的性能原则可归纳为三条主线:
- 循环内零子 shell:用
while read替代for i in $(cat file),用readarray/mapfile替代命令替换填数组; - 内建优先:
[[ ]]替代test,${var//pattern/replacement}替代 sed,$(( ))替代 expr,printf替代echo; - 批量与并行:单次 sed 多表达式、关联数组替代重复 grep、大文件逐行处理、
xargs -P $(nproc)独立任务并行。
配套技能 bash-defensive-patterns 中的 mapfile -t lines < <(some_command) 与 NUL 安全 find -print0 组合正是上述原则的可执行示例。
七、可移植性与版本管理
7.1 跨平台兼容
- Shebang 用
#!/usr/bin/env bash; - 启动时校验 Bash 版本:
(( BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 4 )); - 平台差异用
case "$(uname -s)" in Linux*) ... ;; Darwin*) ... ;; esac分派; - 区分 GNU/BSD 工具差异(如
sed -ivssed -i ''); - 在 Linux、macOS、BSD 全目标平台测试,脚本头部注释注明最低版本要求。
7.2 Bash 5.x 现代特性
bash-pro 单独列出 Bash 5.x 特性矩阵:
- 5.0:关联数组增强、
${var@U}大写转换、${var@L}小写转换; - 5.1:
${parameter@operator}变换增强、compatshopt 兼容选项; - 5.2:
varredir_close选项、改进的exec错误处理、EPOCHREALTIME微秒精度。
使用前必须检查版本:[[ ${BASH_VERSINFO[0]} -ge 5 && ${BASH_VERSINFO[1]} -ge 2 ]]。4.4+ 可用的 @Q(shell 引用输出)、@E(转义序列展开)、@P(提示符展开)、@A(赋值格式)以及 mapfile -d delim 也在文档中列明。若追求 POSIX 兼容,则需对照 posix-shell-pro 的限制清单(无数组、无 [[、无进程替换、无 local 等)。
八、Bats 测试框架:生产级 Shell 测试
bash-pro 明确要求"用 bats-core 或 shellspec 编写 TAP 输出的综合测试套件"。仓库配套技能 bats-testing-patterns 提供了完整范式:
8.1 错误路径测试
@test "Function fails with missing file" {
run my_function "/nonexistent/file.txt"
[ "$status" -ne 0 ]
[[ "$output" == *"not found"* ]]
}
要点是同时测成功与失败路径:缺失文件、非法输入、权限拒绝(chmod 000)、帮助信息([[ "$output" == *"Usage:"* ]])。
8.2 依赖与多 Shell 兼容测试
依赖工具缺失时用 skip,并用 BATS_TEST_DIRNAME 定位被测脚本:
setup() {
if ! command -v jq &>/dev/null; then
skip "jq is not installed"
fi
export SCRIPT="${BATS_TEST_DIRNAME}/../bin/script.sh"
}
多 Shell 矩阵测试则分别用 bash、sh、dash 执行被测脚本,验证可移植性(SKILL.md)。
8.3 测试辅助与 CI 集成
test_helper.sh 模式沉淀 assert_file_exists、assert_file_equals、setup_test_dir 等断言工具;GitHub Actions 中 bats tests/*.bats --tap 输出 TAP 格式;Makefile 提供 test、test-verbose、test-tap、test-parallel 目标。仓库自身的 Makefile 同样遵循"一条命令驱动全部质量门禁"的思路(make validate、make test、make smoke-test)。
九、ShellCheck 静态分析与 shfmt 格式化
9.1 配置与命令行
bash-pro 指定的标准配置为 ShellCheck 的 enable=all + external-sources=true,shfmt 使用 -i 2 -ci -bn -sr -kp。配套技能 shellcheck-configuration 补充了 .shellcheckrc 项目级配置:
shell=bash
enable=avoid-nullary-conditions,require-variable-braces,check-unassigned-uppercase
disable=SC1091
external-sources=true
以及典型命令行组合:shellcheck --shell=bash --exclude=SC1091 --enable=all script.sh。POSIX 项目则用 shellcheck -s sh + shfmt -ln posix(见 posix-shell-pro)。
9.2 高频告警速查
| 告警 | 问题 | 修复 |
|---|---|---|
| SC2086 | 变量未加双引号导致分词/通配 | "$var" |
| SC2181 | 用 $? 间接判断退出码 |
if some_command; then |
| SC2015 | &&/` |
|
| SC2016 | 单引号内不展开变量 | 改双引号 |
| SC2009 | ps aux | grep 查找进程 |
用 pgrep -f |
| SC3010 | POSIX sh 使用 [[ ]] |
用 case |
输出格式方面,--format=gcc 适合 CI 解析,--format=json 适合程序化处理,--format=quiet 只返回退出码。仓库的质量门禁中(见 AGENTS.md),make garden 负责死链与漂移检测,正是"静态分析作为验收标准"的仓库级体现。
十、CI/CD 集成与依赖管理
10.1 管道矩阵
bash-pro 给出的 CI/CD 全景:
- GitHub Actions:接入
shellcheck-problem-matchers实现行内注解; - Pre-commit hooks:
.pre-commit-config.yaml配置shellcheck、shfmt、checkbashisms; - Matrix testing:Bash 4.4/5.0/5.1/5.2 × Linux/macOS 矩阵测试;
- 容器测试:官方
bash:5.2Docker 镜像保证可复现; - CodeQL:开启 Shell 脚本安全扫描;actionlint:校验调用 Shell 的 Actions 工作流;
- 覆盖报告:跟踪测试覆盖率并对回退失败。
标准流水线一行式:shellcheck *.sh && shfmt -d *.sh && bats test/。
10.2 依赖管理
- 包管理:
basher install username/repo@version或bpkg install username/repo -g; - 供应链安全:版本锁定、锁文件、外部脚本校验和核验、Dependabot/Renovate 自动化更新;
- 依赖隔离:不同依赖集分目录存放。
十一、可观测性、日志与文档规范
11.1 结构化日志
bash-pro 给出了 JSON 输出(对接日志聚合)、DEBUG/INFO/WARN/ERROR 分级、syslog 集成与 Prometheus 指标导出。其示例:
log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }
配套技能中的日志函数则统一带时间戳 [$(date +'%Y-%m-%d %H:%M:%S')] INFO: $* 输出到 stderr,log_debug 由 DEBUG 环境变量开关控制(details.md)。
11.2 文档与帮助
- 实现
--help/-h(含用法、选项、示例)与--version; - 头部注释块记录用途、作者、修改日期;文档化所有选项、退出码(0=成功、1=一般错误、特定错误用特定码)、环境变量与前置依赖;
- 用
shdoc从注释生成 Markdown 文档,用shellman生成 man page;复杂脚本用 Mermaid/GraphViz 附架构图。
十二、质量清单与交付物
bash-pro 以一张 Quality Checklist 收束全部实践,可作为任何脚本的验收卡:
- ShellCheck 通过(最少豁免);2. shfmt 统一格式;3. Bats 全覆盖含边界用例;4. 所有变量展开带引号;5. 错误处理覆盖全部失败模式且消息可读;6. EXIT trap 清理临时资源;7. 支持
--help;8. 输入校验防注入;9. Linux/macOS 可移植;10. 性能满足预期负载。
最终交付物包括:生产级脚本、bats-core/shellspec 测试套件(TAP 输出)、GitHub Actions/GitLab CI 配置、shdoc/shellman 文档、.shellcheckrc/.shfmt.toml/.editorconfig 配置、性能基准、SAST/密钥扫描报告、Bash 3→5 迁移指南、Homebrew formula/deb/rpm 打包配置与容器镜像。
十三、常见陷阱速查
bash-pro 明确警告以下高频错误,配套技能 details.md 均提供了替代方案:
| 陷阱 | 后果 | 正确做法 |
|---|---|---|
for f in $(ls ...) |
分词/通配符 bug | find -print0 | while IFS= read -r -d '' f |
| 未加引号的变量展开 | 意外分词 | 一律 "$var" |
复杂流程只靠 set -e |
错误被吞 | 配合 trap ... ERR 与显式退出码检查 |
用 echo 输出数据 |
行为不可预测 | 用 printf |
| 缺少清理 trap | 残留临时文件 | trap 'rm -rf -- "$tmpdir"' EXIT |
| 命令替换填数组 | 换行/空格被破坏 | readarray/mapfile |
结语:把 bash-pro 当作脚本"守门人"
bash-pro 文档实质是一份生产级 Bash 脚本的工程规范清单:防御式编码解决正确性,静态分析与测试解决质量,CI/CD 与文档解决可维护性,安全加固解决信任边界。在 agents24 仓库中,它与 posix-shell-pro 互补——需要极致的可移植性(嵌入式、BusyBox、Solaris)时走 POSIX 路线,需要 Bash 5.x 现代特性与高开发效率时走 bash-pro 路线。配合仓库内的 bash-defensive-patterns、bats-testing-patterns 与 shellcheck-configuration 三套技能,你可以把上述每一条原则直接落成可运行的脚本、测试与流水线。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00