Bash 脚本专业开发指南:自动化、安全与最佳实践 | SkillsMDBash 脚本专业开发指南:自动化、安全与最佳实践
bash-pro by sickn33/antigravity-awesome-skills
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill bash-pro🇨🇳中文介绍
使用场景
- 为自动化、CI/CD 或运维编写或审查 Bash 脚本时
- 为安全性和可移植性加固 shell 脚本时
避免使用场景
- 需要仅支持 POSIX 的 shell 且不能使用 Bash 特性时
- 任务需要更高级的语言来处理复杂逻辑时
- 需要 Windows 原生脚本(PowerShell)时
使用说明
- 定义脚本的输入、输出和故障模式。
- 应用严格模式和安全参数解析。
- 使用防御性模式实现核心逻辑。
- 使用 Bats 和 ShellCheck 添加测试和代码检查。
安全性
- 将输入视为不可信;避免使用
eval 和不安全的通配符展开。
- 在执行破坏性操作前,优先使用试运行模式。
重点领域
- 具有严格错误处理的防御性编程
- POSIX 兼容性和跨平台可移植性
- 安全的参数解析和输入验证
- 稳健的文件操作和临时资源管理
- 进程编排和管道安全性
- 生产级的日志记录和错误报告
- 使用 Bats 框架进行全面的测试
- 使用 ShellCheck 进行静态分析,使用 shfmt 进行格式化
- 现代 Bash 5.x 特性和最佳实践
- CI/CD 集成和自动化工作流
方法
- 始终使用严格模式:
set -Eeuo pipefail 并配合适当的错误捕获
- 引用所有变量展开,以防止单词拆分和通配符问题
- 优先使用数组和正确的迭代,而非不安全的模式,如
for f in $(ls)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
联系我们 在 Bash 条件判断中使用 [[ ]],为保持 POSIX 兼容性可回退到 [ ]使用 getopts 和用法函数实现全面的参数解析使用 mktemp 和清理陷阱安全地创建临时文件和目录为了可预测的输出格式,优先使用 printf 而非 echo为了可读性,使用命令替换 $() 而非反引号实现带有时间戳和可配置详细程度的结构化日志记录设计脚本使其具有幂等性并支持试运行模式在 Bash 4.4+ 中使用 shopt -s inherit_errexit 以获得更好的错误传播使用 IFS=$'\n\t' 防止在空格上发生意外的单词拆分使用 : "${VAR:?message}" 验证必需的环境变量使用 -- 结束选项解析,并使用 rm -rf -- "$dir" 进行安全操作支持 --trace 模式,通过 set -x 选择加入以进行详细调试使用带有 NUL 分隔符的 xargs -0 进行安全的子进程编排使用 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 兼容性时避免使用 bashism,使用 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 钩子 :在
.pre-commit-config.yaml 中配置 shellcheck、shfmt、checkbashisms
- 矩阵测试 :在 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 命令进行系统日志集成
- 分布式追踪 :为多脚本工作流关联添加追踪 ID
- 指标导出 :输出 Prometheus 格式的指标以供监控
- 错误上下文 :在错误日志中包含堆栈跟踪、环境信息
- 日志轮转 :为长时间运行的脚本配置日志文件轮转
- 性能指标 :跟踪执行时间、资源使用情况、外部调用延迟
- 示例:
log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }
质量检查清单
- 脚本通过 ShellCheck 静态分析,且抑制项最少
- 代码使用标准选项通过 shfmt 进行了一致的格式化
- 使用 Bats 进行全面的测试覆盖,包括边界情况
- 所有变量展开都正确引用
- 错误处理覆盖所有故障模式,并提供有意义的错误信息
- 使用 EXIT 陷阱正确清理临时资源
- 脚本支持
--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 公式、deb/rpm 规范)
- 用于可重复执行环境的容器镜像
必备工具
静态分析与格式化
- ShellCheck :静态分析器,配置为
enable=all 和 external-sources=true
- shfmt :Shell 脚本格式化工具,标准配置为(
-i 2 -ci -bn -sr -kp)
- checkbashisms :检测 bash 特定结构以进行可移植性分析
- Semgrep :具有针对 shell 特定安全问题自定义规则的 SAST 工具
- CodeQL :GitHub 的 shell 脚本安全扫描工具
测试框架
- bats-core :Bats 的维护分支,具有现代特性和积极开发
- shellspec :具有丰富断言和模拟功能的 BDD 风格测试框架
- shunit2 :用于 shell 脚本的 xUnit 风格测试框架
- bashing :具有模拟支持和测试隔离功能的测试框架
现代开发工具
- bashly :用于构建命令行应用程序的 CLI 框架生成器
- basher :用于依赖管理的 Bash 包管理器
- bpkg :具有类似 npm 接口的替代性 bash 包管理器
- shdoc :从 shell 脚本注释生成 markdown 文档
- shellman :从 shell 脚本生成 man 页面
CI/CD 与自动化
- pre-commit :多语言预提交钩子框架
- actionlint :GitHub Actions 工作流检查器
- gitleaks :用于防止凭证泄露的密钥扫描工具
- Makefile :用于代码检查、格式化、测试和发布工作流的自动化工具
需避免的常见陷阱
for f in $(ls ...) 导致单词拆分/通配符错误(应使用 find -print0 | while IFS= read -r -d '' f; do ...; done)
- 未引用的变量展开导致意外行为
- 在复杂流程中依赖
set -e 而没有适当的错误捕获
- 使用
echo 进行数据输出(为了可靠性,应优先使用 printf)
- 缺少针对临时文件和目录的清理陷阱
- 不安全的数组填充(应使用
readarray/mapfile 而非命令替换)
- 忽略二进制安全的文件处理(对于文件名,始终考虑使用 NUL 分隔符)
依赖管理
- 包管理器 :使用
basher 或 bpkg 安装 shell 脚本依赖项
- 打包依赖 :将依赖项复制到项目中以实现可重复构建
- 锁定文件 :记录所用依赖项的确切版本
- 校验和验证 :验证外部脚本来源的完整性
- 版本锁定 :将依赖项锁定到特定版本以防止破坏性更改
- 依赖隔离 :为不同的依赖集使用单独的目录
- 更新自动化 :使用 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-documents :
cat <<-'EOF' 中的 - 会去除前导制表符,引号可防止扩展
- 进程管理 :
wait $pid 等待后台作业,jobs -p 列出后台 PID
- 条件执行 :
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 进行自定义计时
参考资料与延伸阅读
风格指南与最佳实践
工具与框架
安全与高级主题
🇺🇸English
Use this skill when
- Writing or reviewing Bash scripts for automation, CI/CD, or ops
- Hardening shell scripts for safety and portability
Do not use this skill when
- You need POSIX-only shell without Bash features
- The task requires a higher-level language for complex logic
- You need Windows-native scripting (PowerShell)
Instructions
- Define script inputs, outputs, and failure modes.
- Apply strict mode and safe argument parsing.
- Implement core logic with defensive patterns.
- Add tests and linting with Bats and ShellCheck.
Safety
- Treat input as untrusted; avoid eval and unsafe globbing.
- Prefer dry-run modes before destructive actions.
Focus Areas
- Defensive programming with strict error handling
- POSIX compliance and cross-platform portability
- Safe argument parsing and input validation
- Robust file operations and temporary resource management
- Process orchestration and pipeline safety
- Production-grade logging and error reporting
- Comprehensive testing with Bats framework
- Static analysis with ShellCheck and formatting with shfmt
- Modern Bash 5.x features and best practices
- CI/CD integration and automation workflows
Approach
- Always use strict mode with
set -Eeuo pipefail and proper error trapping
- Quote all variable expansions to prevent word splitting and globbing issues
- Prefer arrays and proper iteration over unsafe patterns like
for f in $(ls)
- Use
[[ ]] for Bash conditionals, fall back to [ ] for POSIX compliance
- Implement comprehensive argument parsing with
getopts and usage functions
- Create temporary files and directories safely with
mktemp and cleanup traps
- Prefer
printf over echo for predictable output formatting
- Use command substitution
$() instead of backticks for readability
- Implement structured logging with timestamps and configurable verbosity
- Design scripts to be idempotent and support dry-run modes
- Use
shopt -s inherit_errexit for better error propagation in Bash 4.4+
- Employ
IFS=$'\n\t' to prevent unwanted word splitting on spaces
- Validate inputs with
: "${VAR:?message}" for required environment variables
- End option parsing with
-- and use rm -rf -- "$dir" for safe operations
- Support
--trace mode with set -x opt-in for detailed debugging
- Use
xargs -0 with NUL boundaries for safe subprocess orchestration
- Employ
readarray/mapfile for safe array population from command output
- Implement robust script directory detection:
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
- Use NUL-safe patterns:
find -print0 | while IFS= read -r -d '' file; do ...; done
Compatibility & Portability
- Use
#!/usr/bin/env bash shebang for portability across systems
- Check Bash version at script start:
(( BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 4 )) for Bash 4.4+ features
- Validate required external commands exist:
command -v jq &>/dev/null || exit 1
- Detect platform differences:
case "$(uname -s)" in Linux*) ... ;; Darwin*) ... ;; esac
- Handle GNU vs BSD tool differences (e.g.,
sed -i vs sed -i '')
- Test scripts on all target platforms (Linux, macOS, BSD variants)
- Document minimum version requirements in script header comments
- Provide fallback implementations for platform-specific features
- Use built-in Bash features over external commands when possible for portability
- Avoid bashisms when POSIX compliance is required, document when using Bash-specific features
Readability & Maintainability
- Use long-form options in scripts for clarity:
--verbose instead of -v
- Employ consistent naming: snake_case for functions/variables, UPPER_CASE for constants
- Add section headers with comment blocks to organize related functions
- Keep functions under 50 lines; refactor larger functions into smaller components
- Group related functions together with descriptive section headers
- Use descriptive function names that explain purpose:
validate_input_file not check_file
- Add inline comments for non-obvious logic, avoid stating the obvious
- Maintain consistent indentation (2 or 4 spaces, never tabs mixed with spaces)
- Place opening braces on same line for consistency:
function_name() {
- Use blank lines to separate logical blocks within functions
- Document function parameters and return values in header comments
- Extract magic numbers and strings to named constants at top of script
Safety & Security Patterns
- Declare constants with
readonly to prevent accidental modification
- Use
local keyword for all function variables to avoid polluting global scope
- Implement
timeout for external commands: timeout 30s curl ... prevents hangs
- Validate file permissions before operations:
[[ -r "$file" ]] || exit 1
- Use process substitution
<(command) instead of temporary files when possible
- Sanitize user input before using in commands or file operations
- Validate numeric input with pattern matching:
[[ $num =~ ^[0-9]+$ ]]
- Never use
eval on user input; use arrays for dynamic command construction
- Set restrictive umask for sensitive operations:
(umask 077; touch "$secure_file")
Performance Optimization
- Avoid subshells in loops; use
while read instead of for i in $(cat file)
- Use Bash built-ins over external commands:
[[ ]] instead of test, ${var//pattern/replacement} instead of sed
- Batch operations instead of repeated single operations (e.g., one
sed with multiple expressions)
- Use
mapfile/readarray for efficient array population from command output
- Avoid repeated command substitutions; store result in variable once
- Use arithmetic expansion
$(( )) instead of for calculations
Documentation Standards
- Implement
--help and -h flags showing usage, options, and examples
- Provide
--version flag displaying script version and copyright information
- Include usage examples in help output for common use cases
- Document all command-line options with descriptions of their purpose
- List required vs optional arguments clearly in usage message
- Document exit codes: 0 for success, 1 for general errors, specific codes for specific failures
- Include prerequisites section listing required commands and versions
- Add header comment block with script purpose, author, and modification date
- Document environment variables the script uses or requires
- Provide troubleshooting section in help for common issues
- Generate documentation with
shdoc from special comment formats
- Create man pages using
shellman for system integration
- Include architecture diagrams using Mermaid or GraphViz for complex scripts
Modern Bash Features (5.x)
- Bash 5.0 : Associative array improvements,
${var@U} uppercase conversion, ${var@L} lowercase
- Bash 5.1 : Enhanced
${parameter@operator} transformations, compat shopt options for compatibility
- Bash 5.2 :
varredir_close option, improved exec error handling, EPOCHREALTIME microsecond precision
- Check version before using modern features:
[[ ${BASH_VERSINFO[0]} -ge 5 && ${BASH_VERSINFO[1]} -ge 2 ]]
- Use
${parameter@Q} for shell-quoted output (Bash 4.4+)
CI/CD Integration
- GitHub Actions : Use
shellcheck-problem-matchers for inline annotations
- Pre-commit hooks : Configure
.pre-commit-config.yaml with shellcheck, shfmt, checkbashisms
- Matrix testing : Test across Bash 4.4, 5.0, 5.1, 5.2 on Linux and macOS
- Container testing : Use official bash:5.2 Docker images for reproducible tests
- CodeQL : Enable shell script scanning for security vulnerabilities
- Actionlint : Validate GitHub Actions workflow files that use shell scripts
- Automated releases : Tag versions and generate changelogs automatically
- Coverage reporting : Track test coverage and fail on regressions
- Example workflow:
shellcheck *.sh && shfmt -d *.sh && bats test/
Security Scanning & Hardening
- SAST : Integrate Semgrep with custom rules for shell-specific vulnerabilities
- Secrets detection : Use
gitleaks or trufflehog to prevent credential leaks
- Supply chain : Verify checksums of sourced external scripts
- Sandboxing : Run untrusted scripts in containers with restricted privileges
- SBOM : Document dependencies and external tools for compliance
- Security linting : Use ShellCheck with security-focused rules enabled
- Privilege analysis : Audit scripts for unnecessary root/sudo requirements
- Input sanitization : Validate all external inputs against allowlists
- Audit logging : Log all security-relevant operations to syslog
- Container security : Scan script execution environments for vulnerabilities
Observability & Logging
- Structured logging : Output JSON for log aggregation systems
- Log levels : Implement DEBUG, INFO, WARN, ERROR with configurable verbosity
- Syslog integration : Use
logger command for system log integration
- Distributed tracing : Add trace IDs for multi-script workflow correlation
- Metrics export : Output Prometheus-format metrics for monitoring
- Error context : Include stack traces, environment info in error logs
- Log rotation : Configure log file rotation for long-running scripts
- Performance metrics : Track execution time, resource usage, external call latency
- Example:
log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }
Quality Checklist
- Scripts pass ShellCheck static analysis with minimal suppressions
- Code is formatted consistently with shfmt using standard options
- Comprehensive test coverage with Bats including edge cases
- All variable expansions are properly quoted
- Error handling covers all failure modes with meaningful messages
- Temporary resources are cleaned up properly with EXIT traps
- Scripts support
--help and provide clear usage information
- Input validation prevents injection attacks and handles edge cases
- Scripts are portable across target platforms (Linux, macOS)
- Performance is adequate for expected workloads and data sizes
Output
- Production-ready Bash scripts with defensive programming practices
- Comprehensive test suites using bats-core or shellspec with TAP output
- CI/CD pipeline configurations (GitHub Actions, GitLab CI) for automated testing
- Documentation generated with shdoc and man pages with shellman
- Structured project layout with reusable library functions and dependency management
- Static analysis configuration files (.shellcheckrc, .shfmt.toml, .editorconfig)
- Performance benchmarks and profiling reports for critical workflows
- Security review with SAST, secrets scanning, and vulnerability reports
- Debugging utilities with trace modes, structured logging, and observability
- Migration guides for Bash 3→5 upgrades and legacy modernization
- Package distribution configurations (Homebrew formulas, deb/rpm specs)
- Container images for reproducible execution environments
Essential Tools
Static Analysis & Formatting
- ShellCheck : Static analyzer with
enable=all and external-sources=true configuration
- shfmt : Shell script formatter with standard config (
-i 2 -ci -bn -sr -kp)
- checkbashisms : Detect bash-specific constructs for portability analysis
- Semgrep : SAST with custom rules for shell-specific security issues
- CodeQL : GitHub's security scanning for shell scripts
Testing Frameworks
- bats-core : Maintained fork of Bats with modern features and active development
- shellspec : BDD-style testing framework with rich assertions and mocking
- shunit2 : xUnit-style testing framework for shell scripts
- bashing : Testing framework with mocking support and test isolation
Modern Development Tools
- bashly : CLI framework generator for building command-line applications
- basher : Bash package manager for dependency management
- bpkg : Alternative bash package manager with npm-like interface
- shdoc : Generate markdown documentation from shell script comments
- shellman : Generate man pages from shell scripts
CI/CD & Automation
- pre-commit : Multi-language pre-commit hook framework
- actionlint : GitHub Actions workflow linter
- gitleaks : Secrets scanning to prevent credential leaks
- Makefile : Automation for lint, format, test, and release workflows
Common Pitfalls to Avoid
for f in $(ls ...) causing word splitting/globbing bugs (use find -print0 | while IFS= read -r -d '' f; do ...; done)
- Unquoted variable expansions leading to unexpected behavior
- Relying on
set -e without proper error trapping in complex flows
- Using
echo for data output (prefer printf for reliability)
- Missing cleanup traps for temporary files and directories
- Unsafe array population (use
readarray/mapfile instead of command substitution)
- Ignoring binary-safe file handling (always consider NUL separators for filenames)
Dependency Management
- Package managers : Use
basher or bpkg for installing shell script dependencies
- Vendoring : Copy dependencies into project for reproducible builds
- Lock files : Document exact versions of dependencies used
- Checksum verification : Verify integrity of sourced external scripts
- Version pinning : Lock dependencies to specific versions to prevent breaking changes
- Dependency isolation : Use separate directories for different dependency sets
- Update automation : Automate dependency updates with Dependabot or Renovate
- Security scanning : Scan dependencies for known vulnerabilities
- Example:
basher install username/repo@version or bpkg install username/repo -g
Advanced Techniques
- Error Context : Use
trap 'echo "Error at line $LINENO: exit $?" >&2' ERR for debugging
- Safe Temp Handling :
trap 'rm -rf "$tmpdir"' EXIT; tmpdir=$(mktemp -d)
- Version Checking :
(( BASH_VERSINFO[0] >= 5 )) before using modern features
- Binary-Safe Arrays :
readarray -d '' files < <(find . -print0)
- Function Returns : Use
declare -g result for returning complex data from functions
- Associative Arrays :
declare -A config=([host]="localhost" [port]="8080") for complex data structures
- Parameter Expansion :
${filename%.sh} remove extension, basename, replace all
References & Further Reading
Style Guides & Best Practices
- Google Shell Style Guide - Comprehensive style guide covering quoting, arrays, and when to use shell
- Bash Pitfalls - Catalog of common Bash mistakes and how to avoid them
- Bash Hackers Wiki - Comprehensive Bash documentation and advanced techniques
- Defensive BASH Programming - Modern defensive programming patterns
Tools & Frameworks
- ShellCheck - Static analysis tool and extensive wiki documentation
- shfmt - Shell script formatter with detailed flag documentation
- bats-core - Maintained Bash testing framework
- shellspec - BDD-style testing framework for shell scripts
- bashly - Modern Bash CLI framework generator
- shdoc - Documentation generator for shell scripts
Security & Advanced Topics
- Bash Security Best Practices - Security-focused shell script patterns
- Awesome Bash - Curated list of Bash resources and tools
- Pure Bash Bible - Collection of pure bash alternatives to external commands
Weekly Installs
274
Repository
sickn33/antigra…e-skills
GitHub Stars
27.1K
First Seen
Jan 28, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode210
claude-code198
gemini-cli192
github-copilot190
codex183
cursor173
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装
Log security-relevant operations (authentication, privilege changes, file access)Use -- to separate options from arguments: rm -rf -- "$user_input"Validate environment variables before using: : "${REQUIRED_VAR:?not set}"Check exit codes of all security-critical operations explicitlyUse trap to ensure cleanup happens even on abnormal exitexpr
Prefer printf over echo for formatted output (faster and more reliable)Use associative arrays for lookups instead of repeated greppingProcess files line-by-line for large files instead of loading entire file into memoryUse xargs -P for parallel processing when operations are independentUse ${parameter@E} for escape sequence expansion (Bash 4.4+)Use ${parameter@P} for prompt expansion (Bash 4.4+)Use ${parameter@A} for assignment format (Bash 4.4+)Employ wait -n to wait for any background job (Bash 4.3+)Use mapfile -d delim for custom delimiters (Bash 4.4+)${path##*/}
${text//old/new}
Signal Handling : trap cleanup_function SIGHUP SIGINT SIGTERM for graceful shutdownCommand Grouping : { cmd1; cmd2; } > output.log share redirection, ( cd dir && cmd ) use subshell for isolationCo-processes : coproc proc { cmd; }; echo "data" >&"${proc[1]}"; read -u "${proc[0]}" result for bidirectional pipesHere-documents : cat <<-'EOF' with - strips leading tabs, quotes prevent expansionProcess Management : wait $pid to wait for background job, jobs -p list background PIDsConditional Execution : cmd1 && cmd2 run cmd2 only if cmd1 succeeds, cmd1 || cmd2 run cmd2 if cmd1 failsBrace Expansion : touch file{1..10}.txt creates multiple files efficientlyNameref Variables : declare -n ref=varname creates reference to another variable (Bash 4.3+)Improved Error Trapping : set -Eeuo pipefail; shopt -s inherit_errexit for comprehensive error handlingParallel Execution : xargs -P $(nproc) -n 1 command for parallel processing with CPU core countStructured Output : jq -n --arg key "$value" '{key: $key}' for JSON generationPerformance Profiling : Use time -v for detailed resource usage or TIMEFORMAT for custom timing