Shell脚本编写Skill:让每一行自动化脚本都健壮、可移植、可测试
核心结论速览
- 它是什么:
shell-scripting(Shell脚本编写)是一个面向 AI 编程助手的「技能」,把资深运维/DevOps 工程师写 Shell 脚本的经验模式固化下来,让 AI 输出的脚本不再是"能跑一次"的碎片代码,而是带错误处理、参数解析和测试的生产级脚本。 - 解决什么痛点:AI 直接生成的 Shell 脚本常见问题——不引用变量、不检查退出码、不做清理、Linux 上能跑 macOS 上崩、没有
--help也没有测试。 - 核心能力:
set -euo pipefail快速失败、trap清理、getopts与长选项解析、参数扩展速查、jq/yq/awk/sed 集成、ShellCheck 静态检查与 Bats 自动化测试、POSIX sh 与 Bash 的选型决策。 - 适合谁:写 CI/CD 管道脚本的 DevOps、做容器入口点的后端/云原生工程师、需要做备份与日志轮转的运维、以及经常让 AI 帮写脚本但总要返工修 bug 的开发者。
- 一句话价值:把"让 AI 写个脚本"升级为"让 AI 按最佳实践交付一个可维护、可测试、跨平台能跑的脚本资产"。
1. 该技能叫什么?如何一键安装 AI 技能提升开发效率?
基本信息
| 项目 | 内容 |
|---|---|
| 技能中文名 | Shell脚本编写Skill |
| 技能英文名 | shell-scripting |
| 技能 ID | 13390 |
| 定位 | 编写健壮、可移植的 Shell 脚本,具备正确的错误处理、参数解析和测试 |
| 适用任务 | 自动化系统任务、构建 CI/CD 脚本、创建容器入口点 |
它到底解决什么问题?
Shell 脚本是开发和运维中"最容易被低估"的代码形态:它往往被随手写、随手跑、随手丢。通用大模型写 Shell 时,常见缺陷高度集中:
- 变量不加引号,路径带空格就崩;
- 不检查命令退出码,出错后继续往下执行,造成半成品状态;
- 不清理临时文件与锁,重复执行就互相冲撞;
- 平台差异踩坑,
sed -i在 macOS 与 Linux 上行为不同; - 没有参数校验,
$1为空时把整个目录删了; - 没有任何测试,改动一次就心里发慌。
shell-scripting 技能的作用,就是把这套工程规范注入 AI 的生成过程,使输出从一开始就遵循"防御性编程"的默认路径。
"一键安装"AI 技能提升开发效率的思路与步骤
所谓"一键安装技能",本质是把一份经验证的技能描述文件(本技能以 name / description 元信息加正文规范的组织形式提供)挂载到支持技能机制的 AI 客户端或开发平台中,让助手在该领域按统一标准作答,而不是每次重新"碰运气"。
通用流程如下(具体命令、入口地址与支持范围请以官方说明为准):
- 确认前提:你使用的 AI 编程助手/终端助手需支持「技能(Skill)」扩展机制;准备一个工作目录用于存放技能文件与参考文档。
- 获取技能:通过平台提供的技能市场、插件中心或技能仓库入口搜索技能英文名
shell-scripting或技能 ID13390进行安装;若平台以文件形式加载,则将技能说明文件放入约定的技能目录。 - 启用技能:在客户端设置中开启该技能(部分平台支持按项目启用,仅在特定代码仓库生效),确认技能状态为已启用。
- 验证是否生效:新建对话,输入类似"帮我写一个带
--help、参数校验和临时文件清理的备份脚本",观察输出是否自动包含set -euo pipefail、trap ... EXIT、command -v依赖检查等特征;若包含,说明技能已生效。 - 准备配套工具链:为让技能推荐的检查与测试真正可用,建议本地安装
jq、yq、ShellCheck、Bats(macOS 可用brew install系列,Debian/Ubuntu 可用apt-get,具体包名以官方说明为准)。
效率提升的关键点在于"一次装、长期用":技能不是一次性提示词,而是持久的上下文约束。装上之后,你此后所有脚本类请求都会自动带上错误处理、参数解析和可移植性检查,省去反复纠正的沟通成本。
2. 该技能的主要功能和特点
- 明确的选型决策能力:技能内置 POSIX sh 与 Bash 的判断标准——需要最大可移植性(Linux/macOS/BSD/Alpine)、最小化容器镜像、嵌入式或未知目标环境时选
#!/bin/sh;需要数组/关联数组、高级参数扩展、进程替换<(cmd)时选 Bash。这一点是普通代码补全工具完全不具备的。 - 默认开启的快速失败模式:输出脚本默认带
set -euo pipefail,并解释-e、-u、-o pipefail各自的作用,用于生产自动化、CI/CD 与关键操作。 - 成体系的错误处理范式:除快速失败外,还提供显式退出码检查(
if ! cmd; then ... exit 1)与trap cleanup EXIT清理处理器,覆盖临时文件、锁与资源释放。 - 两套参数解析方案:短选项用
getopts(POSIX 兼容,含shift $((OPTIND - 1))收尾),长选项用手动while [[ $# -gt 0 ]]解析,并支持--file=value形式。 - 参数扩展速查:
${var:-default}、${var:=default}、: "${API_KEY:?错误:必需}"、${#var}、${var%.txt}、${var##*/}、${var//old/new}、${var^^}/${var,,}等,避免为了字符串处理而强上awk。 - 常见工具集成范式:jq 提取字段与过滤数组、
jq -e检查字段存在性、yq v4 读取与原地更新 YAML、awk 按分隔符取列、sed 替换、grep 按模式匹配日志。 - 可测试、可 lint:ShellCheck 静态分析(含
--shell=sh的 POSIX 合规检查、--exclude排除规则)、Bats 自动化测试(断言退出码、输出内容与提示文本),并给出bats test/运行方式。 - 防御性编程检查清单:依赖命令检查、环境变量强制、文件存在性检查、变量引用规范(对照
echo $file与echo "$file")。 - 平台差异处理:macOS 与 Linux 的
sed -i差异,并给出"临时文件 + mv"的可移植写法;readlink -f仅 Linux,改用cd "$(dirname "$0")" && pwd。 - 生产脚本模板:提供
readonly SCRIPT_NAME、SCRIPT_DIR、cleanup结合trap、统一log()带时间戳、main "$@"入口等结构的完整模板。 - 边界意识强:明确指出当脚本超过 200 行且逻辑复杂、需要复杂业务逻辑或数据结构、需要跨平台 GUI、大量 API 集成时,应改用 Python/Go——这种"劝退"能力恰恰是专业性的体现。
和普通工具比强在哪? 普通代码补全或通用对话工具只能给出"语法正确"的片段;本技能给出的是"工程正确"的结构化方案,并且同时交付思路(为什么这么写)、模板(照着改)与验证手段(怎么测)。
3. 如何使用该技能?
步骤 1:明确任务类型与目标平台
先说清楚脚本要跑在哪里(Alpine 容器?macOS 本地?CI 的 Ubuntu runner?),这直接决定 sh 还是 Bash 的选型。示例输入:
我要写一个部署前检查脚本,运行在 GitHub Actions 的 Ubuntu runner 上,需要读取
config.yaml里的数据库地址并做连通性检查。
步骤 2:让技能生成骨架
技能会输出带 set -euo pipefail、trap cleanup EXIT、main "$@" 的骨架。典型骨架(技能中提供的生产模板思路):
#!/bin/bash
set -euo pipefail
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TEMP_DIR=""
cleanup() {
local exit_code=$?
rm -rf "$TEMP_DIR"
exit "$exit_code"
}
trap cleanup EXIT
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2
}
main() {
command -v jq >/dev/null 2>&1 || exit 1
log "成功完成"
}
main "$@"
步骤 3:补齐参数解析
短选项场景直接用 getopts:
while getopts "hvf:o:" opt; do
case "$opt" in
h) usage ;;
v) VERBOSE=true ;;
f) INPUT_FILE="$OPTARG" ;;
o) OUTPUT_FILE="$OPTARG" ;;
*) usage ;;
esac
done
shift $((OPTIND - 1))
长选项场景用手动解析,并支持 --file=value:
while [[ $# -gt 0 ]]; do
case "$1" in
--help) usage ;;
--file) INPUT_FILE="$2"; shift 2 ;;
--file=*) INPUT_FILE="${1#*=}"; shift ;;
*) break ;;
esac
done
步骤 4:加入依赖与输入校验
command -v jq >/dev/null 2>&1 || {
echo "错误:需要 jq" >&2
exit 1
}
: "${API_KEY:?错误:需要 API_KEY}"
[ -f "$CONFIG_FILE" ] || {
echo "错误:配置文件未找到:$CONFIG_FILE" >&2
exit 1
}
步骤 5:让技能补充数据读取逻辑
host=$(yq eval '.database.host' config.yaml)
name=$(curl -sSL https://api.example.com/user | jq -r '.name')
步骤 6:生成并执行检查与测试
shellcheck script.sh
shellcheck --shell=sh script.sh
bats test/
Bats 测试示例(断言退出码与首行输出):
@test "脚本运行成功" {
run ./script.sh --help
[ "$status" -eq 0 ]
[ "${lines[0]}" = "用法:script.sh [选项]" ]
}
@test "处理缺少参数" {
run ./script.sh
[ "$status" -eq 1 ]
[[ "$output" =~ "错误" ]]
}
输入/输出说明:输入是你的任务描述 + 目标平台 + 期望命令行接口;输出是一份可直接落盘运行的脚本,外加对应的 ShellCheck 检查方式与 Bats 测试用例。若你的请求属于"复杂业务逻辑/大量 API 集成",技能会主动建议改用 Python/Go,这是一种有价值的负向建议。
4. 同类型竞品对比分析
| 方案名称 | 定位 | 核心功能 | 安装/使用门槛 | 适用场景 | 优势与不足 |
|---|---|---|---|---|---|
| shell-scripting(本技能) | AI 侧的脚本工程规范与生成能力 | 错误处理范式、参数解析、参数扩展、jq/yq 集成、可移植性决策、ShellCheck 与 Bats 指导、生产模板 | 需在支持技能的 AI 客户端启用,具体入口以官方说明为准;上手成本低 | 从零生成脚本、改造旧脚本、CI/CD 与容器入口点 | 优势:一次配置长期生效,同时给思路、模板与测试;不足:依赖 AI 客户端能力,仍需人工复核与本地工具链配合 |
| ShellCheck | 静态分析工具 | 语法与常见陷阱检查、POSIX 合规检查、按规则排除告警 | 需本地安装,命令行直接调用,门槛低 | 提交前的脚本把关 | 优势:权威、精准、可进 CI;不足:只发现问题不给完整重写方案,无法生成脚本 |
| Bats | Shell 脚本自动化测试框架 | 用例编写、退出码与输出断言、批量运行 | 需安装 bats-core,需自己编写用例 | 脚本回归测试 | 优势:贴近 Shell 原生体验;不足:学习曲线存在,且不负责生成被测脚本 |
| 通用 AI 编程助手(直接对话) | 通用代码生成 | 可写 Shell,也能写其他语言 | 零配置 | 简单一次性脚本 | 优势:无门槛;不足:默认不启用防御性规范,常缺 set -euo pipefail、trap、参数校验与测试,返工率高 |
选型建议:三者不是替代关系而是互补关系。shell-scripting 负责"写出对的结构",ShellCheck 负责"静态把关",Bats 负责"行为回归"。通用 AI 助手适合一次性小脚本,但一旦脚本要进 CI、要给别人用、要长期维护,就应该切到本技能的模式。
5. 该技能的典型应用场景与实际体验情况
场景一:CI/CD 管道脚本(DevOps 工程师)
痛点:流水线脚本失败后日志里只有一行 “exit code 1”,无法定位是依赖缺失、参数错误还是网络问题。使用方式:让技能生成带 command -v 依赖检查、trap cleanup EXIT 清理与 log() 带时间戳输出的脚本。实际体验:失败原因从"看不懂"变为"一眼定位",日志统一走 stderr 便于区分正常输出与诊断信息;注意点是 set -e 在管道与非条件判断中语义有差异,复杂分支处应显式使用 if ! cmd。
场景二:容器入口点脚本(云原生/后端工程师)
痛点:Alpine 镜像里没有 Bash,写了 #!/bin/bash 的入口点直接报错。使用方式:声明目标环境为 Alpine,技能会建议选 #!/bin/sh 并在成功后用 shellcheck --shell=sh 校验 POSIX 合规。实际体验:镜像体积与兼容性问题一次性解决;注意事项是 POSIX sh 下没有数组与进程替换,需提前规划数据结构。
场景三:系统管理自动化(运维/SRE)
痛点:备份与日志轮转脚本重复执行时互相覆盖临时文件,或失败后残留锁文件导致下次跑不动。使用方式:用 mktemp 创建临时资源,用 trap cleanup EXIT 保证无论成功失败都执行清理,并在 cleanup 中保留原退出码 local exit_code=$? 后再 exit "$exit_code"。实际体验:脚本可重复执行、可并发,排障成本显著下降;注意事项是 cleanup 内部不要再触发可能失败的命令叠加。
场景四:跨平台开发工具脚本(工具链开发者)
痛点:同一个脚本在同事的 macOS 与本机 Linux 上表现不一致,sed -i '' 与 sed -i 打架。使用方式:让技能给出可移植写法——sed 's/old/new/g' file.txt > file.txt.tmp && mv file.txt.tmp file.txt,以及用 cd "$(dirname "$0")" && pwd 替代仅 Linux 支持的 readlink -f。实际体验:跨平台"一次性通过率"明显提高;注意事项是定位脚本目录的写法要在软链接调用场景下额外验证。
整体上手难度评价:门槛低——你只需要会描述需求;但要真正用好,需要理解 -euo pipefail、trap、getopts 这三组概念,否则容易"抄了模板但不明白为什么"。建议先在一个真实小脚本上跑通"生成 → ShellCheck → Bats 测试"的闭环。
6. 该技能能为用户带来的价值
- 缩短从"想法"到"可交付脚本"的距离:骨架、参数解析、错误处理、清理逻辑、测试用例一次成型,省去反复查文档与试错的时间;对一个中等复杂度的运维脚本,过去常见的半天调试往往能压缩到一次成稿后的少量修正。
- 降低工程门槛:把
trap、getopts、参数扩展、平台差异这些"资深经验"变成默认输出,让不常写 Shell 的后端、前端、数据工程师也能产出符合规范的脚本。 - 减少线上事故面:默认快速失败、默认依赖检查、默认变量引用、默认清理资源,直接对应最常见的几类脚本事故——静默失败、半成品状态、临时文件污染、路径含空格崩溃。
- 让脚本可维护、可测试:ShellCheck 与 Bats 的组合让 Shell 从"改了就怕"的代码变成有质量门的代码,可纳入 CI 流程。
- 避免技术选型错误:明确告知何时不该用 Shell(超 200 行、复杂业务逻辑、大量 API 集成、需要 GUI),把资源投入到更合适的语言上,这本身是长期价值。
- 知识沉淀效应:技能附带的参考文档体系(错误处理、参数解析、参数扩展、可移植性、测试、常用工具)与示例脚本集合,让团队可以围绕统一规范协作,而不是每个人一套风格。
7. 常见问题 FAQ
Q1:这个技能怎么安装?我用的 AI 工具支持吗?
A:本技能以技能说明文件的形式提供(英文名 shell-scripting,技能 ID 13390)。安装方式取决于你所使用的平台是否支持技能机制:可通过平台技能市场/插件中心搜索技能英文名或 ID 安装,也可按平台约定将技能文件放入指定目录后在设置中启用。具体入口、命令与支持范围以官方说明为准。启用后可让助手写一个带 --help 和 trap 清理的脚本,观察输出是否自带 set -euo pipefail 来验证生效。
Q2:这个技能收费吗?
A:技能本身的功能描述中未涉及定价信息,是否收费取决于你获取技能的平台与账户类型,请以官方说明为准。需要注意的是,技能推荐的 ShellCheck、Bats、jq、yq 均为独立的开源工具,按各自项目许可使用。
Q3:它适合谁用?我只会写一点点 Shell 有意义吗?
A:非常适合。技能的价值恰恰在于把规范"外包"给 AI:你描述需求,它输出带错误处理、参数解析与测试的脚本。会用一点点 Shell 的开发者、需要写 CI 脚本的后端工程师、做容器入口点的云原生工程师、以及负责备份与日志轮转的运维人员,都是典型用户。唯一建议是至少能读懂 set -euo pipefail、trap 和 getopts 三段代码的含义,便于复核。
Q4:它和 ShellCheck、Bats 是替代关系吗?
A:不是。shell-scripting 负责"怎么写对",ShellCheck 负责"静态发现问题",Bats 负责"行为回归验证"。技能本身也会指导你使用后两者,并给出 CI 集成思路(如技能提供的 lint 包装脚本与测试包装脚本)。三者配合使用效果最佳。
Q5:用它生成的脚本能直接上生产吗?
A:可以作为高质量起点,但仍需人工复核。至少完成三步:一是用 shellcheck script.sh(POSIX 脚本用 shellcheck --shell=sh)过一遍;二是补一份 Bats 用例覆盖 --help、缺参、错误输入等路径;三是在目标环境(Alpine/macOS/CI runner)实跑验证。此外,如果脚本将超过 200 行且逻辑复杂,技能本身也会建议改用 Python/Go。