指南:基于 agentic-awesome-skills 倉庫的可靠 Shell 腳本模式)
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/下的激活與校驗?zāi)_本到各技能目錄的輔助腳本處處可見防御式 Bash 編程的實踐。本指南以技能bash-defensive-patterns的實施手冊為骨架結(jié)合倉庫內(nèi)真實腳本作為實戰(zhàn)佐證系統(tǒng)講解如何編寫面向生產(chǎn)環(huán)境的健壯 Shell 腳本。讀完本文你將掌握嚴格模式、錯誤捕獲、變量與文件安全、參數(shù)解析、日志與進程編排等一整套可落地的防御模式并能直接應(yīng)用于 CI/CD 流水線、系統(tǒng)運維工具與部署自動化腳本。該技能的使用邊界在 SKILL.md 中有明確說明它適用于編寫生產(chǎn)級自動化腳本、CI/CD 流水線腳本、系統(tǒng)管理工具、容錯部署自動化以及需要跨平臺運行的腳本而當只需要單條臨時命令、目標環(huán)境僅允許嚴格 POSIX sh、或任務(wù)與 Shell 腳本無關(guān)時則不適用。動手前先確認目標 Shell、操作系統(tǒng)與執(zhí)行環(huán)境并始終遵循安全邊界破壞性命令必須有確認或 dry-run 開關(guān)非必要不 root 運行。核心防御原則1. 嚴格模式腳本的第一行保險在每個腳本開頭啟用嚴格模式可以在錯誤發(fā)生的早期階段將其暴露出來#!/bin/bash set -Eeuo pipefail # Exit on error, unset variables, pipe failures四個關(guān)鍵 flag 各司其職set -E讓 ERR trap 在函數(shù)內(nèi)部也能被繼承和觸發(fā)防止錯誤被函數(shù)作用域吞掉set -e任一命令返回非零即退出避免“錯誤被忽略、腳本繼續(xù)執(zhí)行”的連鎖失敗set -u引用未定義變量即退出提前發(fā)現(xiàn)拼寫錯誤或環(huán)境變量缺失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 等大量輔助腳本也采用了相同的嚴格模式說明這是倉庫內(nèi)約定俗成的基線。注意set -e并非萬能。對于你“預(yù)期可能失敗”的命令如grep無匹配、command -v未命中應(yīng)顯式處理例如在 if 條件中使用、追加|| true或用if ! cmd; then ...; fi的形式避免嚴格模式誤傷預(yù)期失敗路徑。2. 錯誤捕獲與清理保證資源不泄漏實現(xiàn)退出或出錯時的清理邏輯是腳本可靠性的第二道防線#!/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保證無論正常結(jié)束還是異常退出都會執(zhí)行清理rm -rf $TMPDIR回收臨時目錄。倉庫中的 scripts/activate-skills.sh 是標準范例腳本用mktemp ${TMPDIR:-/tmp}/ag-skills.XXXXXX創(chuàng)建臨時文件記錄技能清單隨后定義cleanup() { rm -f $SKILLS_LIST_FILE; }并注冊trap cleanup EXIT確保任何退出路徑都不會殘留臨時文件。在后續(xù)小節(jié)中你還會看到用trap配合信號處理來編排后臺進程的模式。3. 變量安全引號是免費的安全網(wǎng)不加引號的變量會被 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是最基礎(chǔ)也是最重要的防御手段: ${REQUIRED_VAR:?REQUIRED_VAR is not set}是“必填變量”慣用法變量未設(shè)置時立即以指定錯誤信息退出適合校驗部署環(huán)境變量、外部傳入?yún)?shù)附帶一提${VAR:-default}與${VAR:default}分別用于“未設(shè)置時取默認值不改寫”和“未設(shè)置時賦默認值改寫”scripts/activate-skills.sh 中大量使用了DEFAULT_BASE_DIR${HOME:-$PWD}/.agents、BASE_DIR${AG_BASE_DIR:-$DEFAULT_BASE_DIR}這類形式通過環(huán)境變量覆蓋默認值兼顧可配置性與安全性。4. 數(shù)組處理復(fù)雜數(shù)據(jù)的安全容器數(shù)組避免了對字符串做IFS分隔的脆弱寫法是處理批量數(shù)據(jù)的推薦方式# 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[]}逐個展開元素區(qū)別于${items[*]}的整體合并即使元素含空格也安全mapfile/readarray -t將命令輸出按行讀入數(shù)組-t去掉行尾換行符。5. 條件判斷安全[[ ]]優(yōu)先[ ]備選# 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 的[[ ]]內(nèi)支持、||、正則匹配、模式匹配且不做分詞與通配展開比[ ]更穩(wěn)健需要跨平臺或嚴格 POSIX 環(huán)境時退化為[ ]此時必須在[ ]之外使用[[ -z ${VAR:-} ]]同時覆蓋“未設(shè)置”和“空字符串”兩種情況是判空的標準寫法?;A(chǔ)防御模式模式 1腳本目錄安全探測$0在通過PATH調(diào)用、符號鏈接或source執(zhí)行時不可靠應(yīng)基于${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實現(xiàn)“腳本放哪兒都能跑”的相對路徑定位。模式 2帶文檔與錯誤處理的函數(shù)模板#!/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 }要點函數(shù)名使用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創(chuàng)建唯一且權(quán)限受限的臨時目錄避免在/tmp下硬編碼文件名造成沖突或安全風險trap rm -rf -- $TMPDIR EXIT保證清理rm -rf --中的--防止目錄名被誤解析為選項。前文提到的 scripts/activate-skills.sh 正是該模式的倉庫實例。模式 4健壯的參數(shù)解析#!/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用--顯式結(jié)束選項解析未知選項報錯并輸出 usage 后以非零狀態(tài)退出選項帶參時如-o、-j用shift 2消耗兩個位置參數(shù)usage() { exit ${1:-0}; }讓 usage 既可用于幫助退出碼 0也可用于報錯退出碼 1。模式 5結(jié)構(gòu)化日志#!/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統(tǒng)一的時間戳 級別格式便于 grep 與后續(xù)解析日志輸出到 stderr2避免污染 stdout 管道數(shù)據(jù)log_debug由環(huán)境變量DEBUG1控制開關(guān)默認關(guān)閉。模式 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用$!記錄每個后臺任務(wù)的 PID 到數(shù)組kill -0 $pid先探測進程是否存活避免向不存在的 PID 發(fā)送信號收到SIGTERM/SIGINT時逐個kill -TERM再wait等待優(yōu)雅退出|| true顯式容忍“進程已退出”這類預(yù)期內(nèi)的失敗防止觸發(fā)嚴格模式退出。模式 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原子改名保證目標文件不會出現(xiàn)“寫了一半”的中間狀態(tài)——讀者若觀察validate-glossary.sh中反復(fù)以{ ... } $OUTPUT_FILE追加報告片段再最后一次性落盤的做法會看到同一“原子性優(yōu)先”的思路。模式 8冪等腳本設(shè)計#!/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冪等的核心是“先查詢狀態(tài)、再決定動作”資源已存在就直接返回成功不存在才創(chuàng)建。這讓腳本可以安全地重復(fù)執(zhí)行如 CI 重跑、定時任務(wù)重放而不會產(chǎn)生累積副作用。scripts/activate-skills.sh 中 “already active”/“restoring” 的分支判斷以及 skills/git-pushing/scripts/smart_commit.sh 這類提交輔助腳本對“重復(fù)執(zhí)行安全”的處理都是冪等設(shè)計的現(xiàn)實體現(xiàn)。模式 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)一律使用$()而非反引號$()支持嵌套、可讀性更好且反引號內(nèi)的反斜杠轉(zhuǎn)義極易出錯$($file)直接從文件讀內(nèi)容比cat少一次子進程關(guān)鍵命令替換后用|| { ...; }顯式處理失敗多行輸出用mapfile -t讀入數(shù)組任意文件名用 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把所有可能產(chǎn)生副作用的命令包裹起來dry-run 模式下只打印將要執(zhí)行的命令而不真正執(zhí)行。這既便于用戶預(yù)覽變更也是技能 SKILL.md 中“破壞性命令必須有確認或 dry-run 開關(guān)”安全要求的直接落點。高級防御技巧命名參數(shù)模式位置參數(shù)在參數(shù)增多時極易錯位函數(shù)內(nèi)改用--keyvalue形式的命名參數(shù)可大幅提升可讀性#!/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 參數(shù)展開用于截取--inputvalue中之后的部分。函數(shù)調(diào)用變?yōu)閜rocess_data --inputx --outputdir --formatjson自文檔化程度遠高于裸位置參數(shù)。依賴檢查腳本依賴外部命令時啟動時集中校驗比用到時再報錯更友好#!/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 內(nèi)置跨平臺一致且不會因非零退出碼在嚴格模式下造成困擾一次性收集所有缺失命令再匯總報錯避免用戶逐個安裝。倉庫中的 scripts/validate-glossary.sh 正是該技巧的實例——腳本開頭即檢查jq是否安裝未安裝時給出針對 Ubuntu/Debian 與 macOS 的安裝提示并退出scripts/activate-skills.sh 的resolve_python函數(shù)則用command -v python3/command -v python依次探測可用的 Python 解釋器都是command -v在真實倉庫中的典型用法。最佳實踐清單速查始終使用嚴格模式——set -Eeuo pipefail引號包裹所有變量——$variable防止分詞優(yōu)先[[ ]]條件判斷—— 比[ ]更穩(wěn)健實現(xiàn)錯誤捕獲—— 優(yōu)雅處理錯誤而非放任崩潰校驗所有輸入—— 檢查文件存在性、權(quán)限與格式用函數(shù)提升復(fù)用性—— 前綴使用有意義的動詞實現(xiàn)結(jié)構(gòu)化日志—— 帶時間戳與級別支持 dry-run 模式—— 允許用戶預(yù)覽變更安全處理臨時文件—— 用mktemp用trap清理面向冪等設(shè)計—— 腳本可安全重跑文檔化需求—— 列出依賴與最低版本測試錯誤路徑—— 確保錯誤處理真的生效用command -v而非which—— 檢查可執(zhí)行程序更安全優(yōu)先printf而非echo—— 跨系統(tǒng)輸出行為更可預(yù)測。綜合實戰(zhàn)一個融合全部模式的腳本骨架將上文模式串聯(lián)起來一個生產(chǎn)級腳本應(yīng)具備如下骨架可在倉庫 scripts/activate-skills.sh、scripts/validate-links.sh、scripts/validate-glossary.sh 中看到對應(yīng)實現(xiàn)#!/usr/bin/env bashset -Eeuo pipefail基于${BASH_SOURCE[0]}計算SCRIPT_DIR與項目根定義帶log_*前綴的結(jié)構(gòu)化日志函數(shù)啟動時check_dependencies校驗外部命令聲明默認值用while/case解析參數(shù)校驗必填項mktemp創(chuàng)建臨時區(qū)注冊trap cleanup EXIT必要時疊加SIGTERM/SIGINT所有破壞性操作經(jīng)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倉庫實戰(zhàn)范例一技能激活腳本嚴格模式、腳本目錄探測、mktemptrap、NUL 迭代、冪等—— scripts/activate-skills.sh倉庫實戰(zhàn)范例二文檔鏈接校驗?zāi)_本嚴格模式、嵌入式 Python heredoc、路徑歸一化—— scripts/validate-links.sh倉庫實戰(zhàn)范例三術(shù)語表一致性校驗依賴檢查、輸出重定向組織報告、退出碼語義—— scripts/validate-glossary.sh技能庫中的更多防御式腳本示例skills/git-pushing/scripts/smart_commit.sh、skills/wiki-builder/scripts/init_wiki.sh注意本文所有命令與配置以當前倉庫實際內(nèi)容為準。在應(yīng)用到具體環(huán)境前請結(jié)合實際 Shell 版本Bash 4 才支持mapfile等特性、目標操作系統(tǒng)與安全邊界做驗證必要時補充測試覆蓋錯誤路徑——防御式編程的最后一公里永遠是充分的測試與人工復(fù)核。贊分享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點擊查看免費下載相關(guān)推薦agentic-awesome-skills 之 Bash Defensive Patterns生產(chǎn)級 Shell 腳本的防御式編程實戰(zhàn)指南agentic awesome skills 之 Bash Defensive Patterns生產(chǎn)級 Shell 腳本的防御式編程實戰(zhàn)指南 本篇指南以 agAI 技能AI 插件人工智能RVC 變聲器 10 分鐘上手從一段音頻到完整實時變聲的入門指南RVC 變聲器 10 分鐘上手從一段音頻到完整實時變聲的入門指南 RVCRetrieval based Voice Conversion WebUI是一個人工智能深度學習語音音頻AI 應(yīng)用微調(diào)autoskills 防御式 Bash 編程實戰(zhàn)指南從 strict mode 到生產(chǎn)級腳本的完整模式庫autoskills 防御式 Bash 編程實戰(zhàn)指南從 strict mode 到生產(chǎn)級腳本的完整模式庫 導讀 本文是 autoskills 技能庫中 bas上一篇Blender 3MF插件3D打印工作流的完整解決方案下一篇如何快速掌握Blender 3MF插件完整使用教程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考