
AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载在 agentic-awesome-skills 仓库中从scripts/下的激活与校验脚本到各技能目录的辅助脚本处处可见防御式 Bash 编程的实践。本指南以技能bash-defensive-patterns的实施手册为骨架结合仓库内真实脚本作为实战佐证系统讲解如何编写面向生产环境的健壮 Shell 脚本。读完本文你将掌握严格模式、错误捕获、变量与文件安全、参数解析、日志与进程编排等一整套可落地的防御模式并能直接应用于 CI/CD 流水线、系统运维工具与部署自动化脚本。该技能的使用边界在 SKILL.md 中有明确说明它适用于编写生产级自动化脚本、CI/CD 流水线脚本、系统管理工具、容错部署自动化以及需要跨平台运行的脚本而当只需要单条临时命令、目标环境仅允许严格 POSIX sh、或任务与 Shell 脚本无关时则不适用。动手前先确认目标 Shell、操作系统与执行环境并始终遵循安全边界破坏性命令必须有确认或 dry-run 开关非必要不 root 运行。核心防御原则1. 严格模式脚本的第一行保险在每个脚本开头启用严格模式可以在错误发生的早期阶段将其暴露出来#!/bin/bash set -Eeuo pipefail # Exit on error, unset variables, pipe failures四个关键 flag 各司其职set -E让 ERR trap 在函数内部也能被继承和触发防止错误被函数作用域吞掉set -e任一命令返回非零即退出避免“错误被忽略、脚本继续执行”的连锁失败set -u引用未定义变量即退出提前发现拼写错误或环境变量缺失set -o pipefail管道中任一命令失败即整体失败而非只看最后一个命令的退出码。仓库中的真实脚本是这一原则的直接印证。scripts/validate-glossary.sh 与 scripts/validate-links.sh 都在首行#!/bin/bash之后立即启用set -euo pipefailscripts/activate-skills.sh 使用#!/usr/bin/env bash以便在PATH中查找 bash同样紧跟set -euo pipefail。技能目录下如 skills/git-pushing/scripts/smart_commit.sh、skills/wiki-builder/scripts/init_wiki.sh 等大量辅助脚本也采用了相同的严格模式说明这是仓库内约定俗成的基线。注意set -e并非万能。对于你“预期可能失败”的命令如grep无匹配、command -v未命中应显式处理例如在 if 条件中使用、追加|| true或用if ! cmd; then ...; fi的形式避免严格模式误伤预期失败路径。2. 错误捕获与清理保证资源不泄漏实现退出或出错时的清理逻辑是脚本可靠性的第二道防线#!/bin/bash set -Eeuo pipefail trap echo Error on line $LINENO ERR trap echo Cleaning up...; rm -rf $TMPDIR EXIT TMPDIR$(mktemp -d) # Script code heretrap ... ERR在任意命令失败时打印出错行号配合$LINENO可以快速定位故障点trap ... EXIT保证无论正常结束还是异常退出都会执行清理rm -rf $TMPDIR回收临时目录。仓库中的 scripts/activate-skills.sh 是标准范例脚本用mktemp ${TMPDIR:-/tmp}/ag-skills.XXXXXX创建临时文件记录技能清单随后定义cleanup() { rm -f $SKILLS_LIST_FILE; }并注册trap cleanup EXIT确保任何退出路径都不会残留临时文件。在后续小节中你还会看到用trap配合信号处理来编排后台进程的模式。3. 变量安全引号是免费的安全网不加引号的变量会被 Bash 分词word splitting和路径展开globbing影响文件名含空格或*时极易出事故# Wrong - unsafe cp $source $dest # Correct - safe cp $source $dest # Required variables - fail with message if unset : ${REQUIRED_VAR:?REQUIRED_VAR is not set}双引号包裹$variable是最基础也是最重要的防御手段: ${REQUIRED_VAR:?REQUIRED_VAR is not set}是“必填变量”惯用法变量未设置时立即以指定错误信息退出适合校验部署环境变量、外部传入参数附带一提${VAR:-default}与${VAR:default}分别用于“未设置时取默认值不改写”和“未设置时赋默认值改写”scripts/activate-skills.sh 中大量使用了DEFAULT_BASE_DIR${HOME:-$PWD}/.agents、BASE_DIR${AG_BASE_DIR:-$DEFAULT_BASE_DIR}这类形式通过环境变量覆盖默认值兼顾可配置性与安全性。4. 数组处理复杂数据的安全容器数组避免了对字符串做IFS分隔的脆弱写法是处理批量数据的推荐方式# Safe array iteration declare -a items(item 1 item 2 item 3) for item in ${items[]}; do echo Processing: $item done # Reading output into array safely mapfile -t lines (some_command) readarray -t numbers (seq 1 10)${items[]}逐个展开元素区别于${items[*]}的整体合并即使元素含空格也安全mapfile/readarray -t将命令输出按行读入数组-t去掉行尾换行符。5. 条件判断安全[[ ]]优先[ ]备选# Bash - safer if [[ -f $file -r $file ]]; then content$($file) fi # POSIX - portable if [ -f $file ] [ -r $file ]; then content$(cat $file) fi # Test for existence before operations if [[ -z ${VAR:-} ]]; then echo VAR is not set or is empty fiBash 的[[ ]]内支持、||、正则匹配、模式匹配且不做分词与通配展开比[ ]更稳健需要跨平台或严格 POSIX 环境时退化为[ ]此时必须在[ ]之外使用[[ -z ${VAR:-} ]]同时覆盖“未设置”和“空字符串”两种情况是判空的标准写法。基础防御模式模式 1脚本目录安全探测$0在通过PATH调用、符号链接或source执行时不可靠应基于${BASH_SOURCE[0]}计算#!/bin/bash set -Eeuo pipefail # Correctly determine script directory SCRIPT_DIR$(cd -- $(dirname -- ${BASH_SOURCE[0]}) pwd -P) SCRIPT_NAME$(basename -- ${BASH_SOURCE[0]}) echo Script location: $SCRIPT_DIR/$SCRIPT_NAME--防止目录名以-开头被当成选项pwd -P解析符号链接得到物理路径。仓库脚本 scripts/activate-skills.sh 和 scripts/validate-links.sh 均采用此模式定位自身并进一步以SCRIPT_DIR推导PROJECT_ROOT与REPO_SKILLS_DIR实现“脚本放哪儿都能跑”的相对路径定位。模式 2带文档与错误处理的函数模板#!/bin/bash set -Eeuo pipefail # Prefix for functions: handle_*, process_*, check_*, validate_* # Include documentation and error handling validate_file() { local -r file$1 local -r message${2:-File not found: $file} if [[ ! -f $file ]]; then echo ERROR: $message 2 return 1 fi return 0 } process_files() { local -r input_dir$1 local -r output_dir$2 # Validate inputs [[ -d $input_dir ]] || { echo ERROR: input_dir not a directory 2; return 1; } # Create output directory if needed mkdir -p $output_dir || { echo ERROR: Cannot create output_dir 2; return 1; } # Process files safely while IFS read -r -d file; do echo Processing: $file # Do work done (find $input_dir -maxdepth 1 -type f -print0) return 0 }要点函数名使用handle_*、process_*、check_*、validate_*等语义前缀可读性高local -r声明只读局部变量避免污染全局每个可能失败的步骤都校验前置条件并输出到 stderr2返回非零退出码while IFS read -r -d 搭配find ... -print0是 NUL 分隔的安全迭代能正确处理文件名中的空格、换行甚至特殊字符。模式 3临时文件的安全处理#!/bin/bash set -Eeuo pipefail trap rm -rf -- $TMPDIR EXIT # Create temporary directory TMPDIR$(mktemp -d) || { echo ERROR: Failed to create temp directory 2; exit 1; } # Create temporary files in directory TMPFILE1$TMPDIR/temp1.txt TMPFILE2$TMPDIR/temp2.txt # Use temporary files touch $TMPFILE1 $TMPFILE2 echo Temp files created in: $TMPDIRmktemp -d创建唯一且权限受限的临时目录避免在/tmp下硬编码文件名造成冲突或安全风险trap rm -rf -- $TMPDIR EXIT保证清理rm -rf --中的--防止目录名被误解析为选项。前文提到的 scripts/activate-skills.sh 正是该模式的仓库实例。模式 4健壮的参数解析#!/bin/bash set -Eeuo pipefail # Default values VERBOSEfalse DRY_RUNfalse OUTPUT_FILE THREADS4 usage() { cat EOF Usage: $0 [OPTIONS] Options: -v, --verbose Enable verbose output -d, --dry-run Run without making changes -o, --output FILE Output file path -j, --jobs NUM Number of parallel jobs -h, --help Show this help message EOF exit ${1:-0} } # Parse arguments while [[ $# -gt 0 ]]; do case $1 in -v|--verbose) VERBOSEtrue shift ;; -d|--dry-run) DRY_RUNtrue 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 # Validate required arguments [[ -n $OUTPUT_FILE ]] || { echo ERROR: -o/--output is required 2; usage 1; }模式要点先声明默认值再解析覆盖最后校验必填项同时支持短选项-v与长选项--verbose用--显式结束选项解析未知选项报错并输出 usage 后以非零状态退出选项带参时如-o、-j用shift 2消耗两个位置参数usage() { exit ${1:-0}; }让 usage 既可用于帮助退出码 0也可用于报错退出码 1。模式 5结构化日志#!/bin/bash set -Eeuo pipefail # Logging functions log_info() { echo [$(date %Y-%m-%d %H:%M:%S)] INFO: $* 2 } log_warn() { echo [$(date %Y-%m-%d %H:%M:%S)] WARN: $* 2 } log_error() { echo [$(date %Y-%m-%d %H:%M:%S)] ERROR: $* 2 } log_debug() { if [[ ${DEBUG:-0} 1 ]]; then echo [$(date %Y-%m-%d %H:%M:%S)] DEBUG: $* 2 fi } # Usage log_info Starting script log_debug Debug information log_warn Warning message log_error Error occurred统一的时间戳 级别格式便于 grep 与后续解析日志输出到 stderr2避免污染 stdout 管道数据log_debug由环境变量DEBUG1控制开关默认关闭。模式 6带信号处理的进程编排#!/bin/bash set -Eeuo pipefail # Track background processes PIDS() cleanup() { log_info Shutting down... # Terminate all background processes for pid in ${PIDS[]}; do if kill -0 $pid 2/dev/null; then kill -TERM $pid 2/dev/null || true fi done # Wait for graceful shutdown for pid in ${PIDS[]}; do wait $pid 2/dev/null || true done } trap cleanup SIGTERM SIGINT # Start background tasks background_task PIDS($!) another_task PIDS($!) # Wait for all background processes wait用$!记录每个后台任务的 PID 到数组kill -0 $pid先探测进程是否存活避免向不存在的 PID 发送信号收到SIGTERM/SIGINT时逐个kill -TERM再wait等待优雅退出|| true显式容忍“进程已退出”这类预期内的失败防止触发严格模式退出。模式 7安全的文件操作#!/bin/bash set -Eeuo pipefail # Use -i flag to move safely without overwriting safe_move() { local -r source$1 local -r dest$2 if [[ ! -e $source ]]; then echo ERROR: Source does not exist: $source 2 return 1 fi if [[ -e $dest ]]; then echo ERROR: Destination already exists: $dest 2 return 1 fi mv $source $dest } # Safe directory cleanup safe_rmdir() { local -r dir$1 if [[ ! -d $dir ]]; then echo ERROR: Not a directory: $dir 2 return 1 fi # Use -I flag to prompt before rm (BSD/GNU compatible) rm -rI -- $dir } # Atomic file writes atomic_write() { local -r target$1 local -r tmpfile tmpfile$(mktemp) || return 1 # Write to temp file first cat $tmpfile # Atomic rename mv $tmpfile $target }三个子模式的共同思路都是“先校验再操作”safe_move检查源存在、目标不存在杜绝覆盖safe_rmdir只接受目录且用rm -rI交互式确认BSD/GNU 兼容atomic_write先写临时文件再mv原子改名保证目标文件不会出现“写了一半”的中间状态——读者若观察validate-glossary.sh中反复以{ ... } $OUTPUT_FILE追加报告片段再最后一次性落盘的做法会看到同一“原子性优先”的思路。模式 8幂等脚本设计#!/bin/bash set -Eeuo pipefail # Check if resource already exists ensure_directory() { local -r dir$1 if [[ -d $dir ]]; then log_info Directory already exists: $dir return 0 fi mkdir -p $dir || { log_error Failed to create directory: $dir return 1 } log_info Created directory: $dir } # Ensure configuration state ensure_config() { local -r config_file$1 local -r default_value$2 if [[ ! -f $config_file ]]; then echo $default_value $config_file log_info Created config: $config_file fi } # Rerunning script multiple times should be safe ensure_directory /var/cache/myapp ensure_config /etc/myapp/config DEBUGfalse幂等的核心是“先查询状态、再决定动作”资源已存在就直接返回成功不存在才创建。这让脚本可以安全地重复执行如 CI 重跑、定时任务重放而不会产生累积副作用。scripts/activate-skills.sh 中 “already active”/“restoring” 的分支判断以及 skills/git-pushing/scripts/smart_commit.sh 这类提交辅助脚本对“重复执行安全”的处理都是幂等设计的现实体现。模式 9安全的命令替换#!/bin/bash set -Eeuo pipefail # Use $() instead of backticks name$($file) # Modern, safe variable assignment from file output$(command -v python3) # Get command location safely # Handle command substitution with error checking result$(command -v node) || { log_error node command not found return 1 } # For multiple lines mapfile -t lines (grep pattern $file) # NUL-safe iteration while IFS read -r -d file; do echo Processing: $file done (find /path -type f -print0)一律使用$()而非反引号$()支持嵌套、可读性更好且反引号内的反斜杠转义极易出错$($file)直接从文件读内容比cat少一次子进程关键命令替换后用|| { ...; }显式处理失败多行输出用mapfile -t读入数组任意文件名用 NUL 分隔的read -r -d 迭代。模式 10Dry-Run 支持#!/bin/bash set -Eeuo pipefail DRY_RUN${DRY_RUN:-false} run_cmd() { if [[ $DRY_RUN true ]]; then echo [DRY RUN] Would execute: $* return 0 fi $ } # Usage run_cmd cp $source $dest run_cmd rm $file run_cmd chown $owner $targetrun_cmd把所有可能产生副作用的命令包裹起来dry-run 模式下只打印将要执行的命令而不真正执行。这既便于用户预览变更也是技能 SKILL.md 中“破坏性命令必须有确认或 dry-run 开关”安全要求的直接落点。高级防御技巧命名参数模式位置参数在参数增多时极易错位函数内改用--keyvalue形式的命名参数可大幅提升可读性#!/bin/bash set -Eeuo pipefail process_data() { local input_file local output_dir local formatjson # Parse named parameters while [[ $# -gt 0 ]]; do case $1 in --input*) input_file${1#*} ;; --output*) output_dir${1#*} ;; --format*) format${1#*} ;; *) echo ERROR: Unknown parameter: $1 2 return 1 ;; esac shift done # Validate required parameters [[ -n $input_file ]] || { echo ERROR: --input is required 2; return 1; } [[ -n $output_dir ]] || { echo ERROR: --output is required 2; return 1; } }${1#*}是 Bash 参数展开用于截取--inputvalue中之后的部分。函数调用变为process_data --inputx --outputdir --formatjson自文档化程度远高于裸位置参数。依赖检查脚本依赖外部命令时启动时集中校验比用到时再报错更友好#!/bin/bash set -Eeuo pipefail check_dependencies() { local -a missing_deps() local -a required(jq curl git) for cmd in ${required[]}; do if ! command -v $cmd /dev/null; then missing_deps($cmd) fi done if [[ ${#missing_deps[]} -gt 0 ]]; then echo ERROR: Missing required commands: ${missing_deps[*]} 2 return 1 fi } check_dependencies使用command -v而非whichcommand -v是 POSIX 内置跨平台一致且不会因非零退出码在严格模式下造成困扰一次性收集所有缺失命令再汇总报错避免用户逐个安装。仓库中的 scripts/validate-glossary.sh 正是该技巧的实例——脚本开头即检查jq是否安装未安装时给出针对 Ubuntu/Debian 与 macOS 的安装提示并退出scripts/activate-skills.sh 的resolve_python函数则用command -v python3/command -v python依次探测可用的 Python 解释器都是command -v在真实仓库中的典型用法。最佳实践清单速查始终使用严格模式——set -Eeuo pipefail引号包裹所有变量——$variable防止分词优先[[ ]]条件判断—— 比[ ]更稳健实现错误捕获—— 优雅处理错误而非放任崩溃校验所有输入—— 检查文件存在性、权限与格式用函数提升复用性—— 前缀使用有意义的动词实现结构化日志—— 带时间戳与级别支持 dry-run 模式—— 允许用户预览变更安全处理临时文件—— 用mktemp用trap清理面向幂等设计—— 脚本可安全重跑文档化需求—— 列出依赖与最低版本测试错误路径—— 确保错误处理真的生效用command -v而非which—— 检查可执行程序更安全优先printf而非echo—— 跨系统输出行为更可预测。综合实战一个融合全部模式的脚本骨架将上文模式串联起来一个生产级脚本应具备如下骨架可在仓库 scripts/activate-skills.sh、scripts/validate-links.sh、scripts/validate-glossary.sh 中看到对应实现#!/usr/bin/env bashset -Eeuo pipefail基于${BASH_SOURCE[0]}计算SCRIPT_DIR与项目根定义带log_*前缀的结构化日志函数启动时check_dependencies校验外部命令声明默认值用while/case解析参数校验必填项mktemp创建临时区注册trap cleanup EXIT必要时叠加SIGTERM/SIGINT所有破坏性操作经run_cmd包装支持DRY_RUN批量处理一律走 NUL 分隔的while IFS read -r -d 或mapfile幂等化每个ensure_*步骤可安全重跑。延伸资源技能入口与使用边界plugins/agentic-awesome-skills-claude/skills/bash-defensive-patterns/SKILL.md模式与模板全量参考resources/implementation-playbook.md仓库实战范例一技能激活脚本严格模式、脚本目录探测、mktemptrap、NUL 迭代、幂等—— scripts/activate-skills.sh仓库实战范例二文档链接校验脚本严格模式、嵌入式 Python heredoc、路径归一化—— scripts/validate-links.sh仓库实战范例三术语表一致性校验依赖检查、输出重定向组织报告、退出码语义—— scripts/validate-glossary.sh技能库中的更多防御式脚本示例skills/git-pushing/scripts/smart_commit.sh、skills/wiki-builder/scripts/init_wiki.sh注意本文所有命令与配置以当前仓库实际内容为准。在应用到具体环境前请结合实际 Shell 版本Bash 4 才支持mapfile等特性、目标操作系统与安全边界做验证必要时补充测试覆盖错误路径——防御式编程的最后一公里永远是充分的测试与人工复核。赞分享AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载相关推荐agentic-awesome-skills 之 Bash Defensive Patterns生产级 Shell 脚本的防御式编程实战指南agentic awesome skills 之 Bash Defensive Patterns生产级 Shell 脚本的防御式编程实战指南 本篇指南以 agAI 技能AI 插件人工智能RVC 变声器 10 分钟上手从一段音频到完整实时变声的入门指南RVC 变声器 10 分钟上手从一段音频到完整实时变声的入门指南 RVCRetrieval based Voice Conversion WebUI是一个人工智能深度学习语音音频AI 应用微调autoskills 防御式 Bash 编程实战指南从 strict mode 到生产级脚本的完整模式库autoskills 防御式 Bash 编程实战指南从 strict mode 到生产级脚本的完整模式库 导读 本文是 autoskills 技能库中 bas上一篇Blender 3MF插件3D打印工作流的完整解决方案下一篇如何快速掌握Blender 3MF插件完整使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考