plugins/languages/bash/skills/core/SKILL.md
Bash / Shell core conventions covering Bash 5.2+ features, POSIX sh portability, strict mode (set -euo pipefail + IFS), quoting and parameter expansion, $(...) over backticks, printf over echo -e, [[ ]] over [ ], shebang selection, and macOS bash 3.2 legacy compatibility. Use when writing, reviewing, refactoring, or debugging any shell script. Also triggers on "Bash 脚本", "shell 脚本规范", "strict mode", "set -euo pipefail", "shellcheck", "shfmt", "POSIX sh 兼容", "bash 5.2", "macOS bash 3.2".
npx skillsauth add lazygophers/ccplugin bash-coreInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
应作为所有 Shell 任务(开发 / 调试 / 优化)的标准基线。其它 bash skill 在本文之上做领域细化。
| 主题 | 跳转 |
|------|------|
| 错误处理 / trap / exit code | bash-error |
| POSIX sh 兼容 / 跨 shell | bash-posix |
| 测试 / bats-core | bash-testing |
| 工具链 / shellcheck / shfmt | bash-tooling |
#!/usr/bin/env bash,POSIX sh 用 #!/bin/sh。shebang → set -euo pipefail → IFS=$'\n\t'。"${var}" 而非 $var,防止字段分割和 glob 展开。$(...) 而非 `...`,允许嵌套且更清晰。[[ ]](bash) 或 [ ](POSIX sh),禁止裸 test。printf '%s\n' 而非 echo -e(echo 的转义行为不可移植)。name() { ... }(不写 function name),便于 POSIX 兼容。local(bash) / 单独函数(POSIX sh)。shellcheck 与 shfmt 检查,零警告。eval 与 source 不受信内容;禁 cd $foo 无引号;禁未引号的 rm -rf $path。#!/usr/bin/env bash
# brief: 描述脚本目的
# usage: ./script.sh [args]
set -euo pipefail
IFS=$'\n\t'
# -e: 任意命令失败立即退出
# -u: 引用未定义变量立即退出
# -o pipefail: 管道中任意命令失败传播退出码
# IFS: 仅按换行和制表符分割,避免空格陷阱
POSIX sh 版本(无 pipefail):
#!/bin/sh
set -eu
# pipefail 在 POSIX 不可用;通过临时文件或 wait 显式处理
| 特性 | 语法 | 用途 |
|------|------|------|
| ${var@U/L/Q/E/P/A/K/a} | 参数转换 | 大小写 / 引号化 / 转义 |
| wait -p var | 等待并取 PID | 后台作业管理 |
| read -d '' | 读到 NUL | 安全处理含换行字段 |
| BASH_ARGV0 | 重写 $0 | 日志友好 |
| EPOCHSECONDS / EPOCHREALTIME | 内置时间 | 免 fork date |
| mapfile -d | 自定义分隔符 | 数组装载 |
| globskipdots | shopt | * 不再匹配 . / .. |
| 关联数组 | declare -A | 字典(Bash 4+) |
| ${var,,} / ${var^^} | 小写 / 大写 | 字符串处理 |
# ✅ 总是引用变量
name="hello world"
echo "${name}" # hello world
echo "$name" # 同上(最简形式)
# ✅ 数组展开必须 "${arr[@]}"
files=(a.txt "b c.txt")
for f in "${files[@]}"; do printf '%s\n' "$f"; done
# ❌ 未引号 → 字段分割 + glob
echo $name # 双词;若含 * 会展开
# ✅ 命令替换嵌套
size=$(du -sh "$(realpath "${path}")" | awk '{print $1}')
# ✅ 默认值 / 必需值
: "${VAR:=default}" # 未设置则赋默认
: "${REQUIRED:?must be set}" # 未设置则报错退出
# ✅ [[ ]] 支持模式 / 正则
[[ "${file}" == *.txt ]] && echo "text"
[[ "${str}" =~ ^[0-9]+$ ]] && echo "numeric"
# ✅ 算术比较
(( count > 0 )) && echo "non-empty"
# ✅ 算术赋值(不需要 $)
(( total = a + b ))
# ❌ 旧式 [ ](POSIX 限制;bash 内首选 [[ ]])
[ "$x" = "$y" ]
# ✅ 标准定义
greet() {
local name="${1:?missing name}"
local prefix="${2:-Hello}"
printf '%s, %s!\n' "${prefix}" "${name}"
}
# ✅ 返回值通过 stdout,状态通过 return
parse_count() {
local input="$1"
if [[ "${input}" =~ ^[0-9]+$ ]]; then
printf '%s' "${input}"
return 0
fi
return 1
}
count=$(parse_count "42") || { echo "bad input" >&2; exit 1; }
# ✅ 日志分级到 stderr,结果到 stdout
log() { printf '[%(%Y-%m-%dT%H:%M:%S)T] %s\n' -1 "$*" >&2; }
die() { log "FATAL: $*"; exit 1; }
warn() { log "WARN: $*"; }
# ✅ heredoc
cat <<EOF
config:
user: ${USER}
pwd: ${PWD}
EOF
# ✅ 不展开的 heredoc(保留 $)
cat <<'EOF'
literal $VAR
EOF
# ❌ 引发血案
rm -rf $path/
# ✅ 防御
[[ -n "${path:-}" ]] || die "path empty"
[[ "${path}" != "/" ]] || die "refuse to rm /"
rm -rf -- "${path}" # `--` 阻止 -name 当作选项
bash 用 env bash)set -euo pipefail + IFS=$'\n\t'"${var}"$(...)echo -e,统一 printfeval / 无未引号 rm -rftools
--- name: trellisx-workspace description: 维护 `.trellis/task.md` 任务看板 —— trellis 缺的跨任务总览。**一个表格, 一行一个任务**, 列为 id/名称/描述/状态/阶段/进度/worktree (状态/阶段中文显示)。在 task create/start/阶段切换/archive 后**及时更新**对应行; 并**自动清理超 7 天的已完成行**防膨胀。保持看板与 task.json 实时一致。 when_to_use: 维护 / 创建 / 更新 `.trellis/task.md` 任务看板时; task 生命周期任一节点 (create/start/阶段推进/archive) 之后同步看板时; 用户问"当前有哪些任务 / 任务进度 / 任务看板"时。被 trellisx-flow 与 trellisx-apply 注入的流程引用。 user-invocable: true argument-hint: [show|update|sync|cleanup ...] [task id] arguments:
testing
强制以 Trellis task 闭环处理用户指定的请求 (自判新建/并入 → plan→exec→check→finish 全程不跳步)。**仅用户显式主动调用** (/trellisx-flow 或明确要求"强制走 task 处理这个"); **禁止自动 / 被动 / 推断式调用** —— 不要因为某个请求"看起来该建 task"就自动触发本 skill, 那是 apply 注入的 no_task 倾向的职责。
testing
把 强推task + subtask拆分 + worktree隔离 + 闭环收尾 四维度增量注入当前项目 .trellis/ (workflow.md 的 no_task/planning/in_progress 块 + spec 背书文档 + trellis 生命周期 hook worktree 自动化)。强推 task 与闭环为纯 prompt 软约束 (非平台 hook 硬拦截)。**纯增量追加, 绝不替换 trellis 原生文本** (no_task 分类+征同意/check/finish/前缀全保留)。幂等 (marker 包裹)。
development
Claude Code 会话历史整理 — 扫 ~/.claude/projects/**/*.jsonl 全部 session transcripts, 提取学习增量 (用户校正/决策/踩坑/L0 规则) → 全局记忆库 ~/.cortex/.wiki/memory/. 默认 --apply 落盘 (--dry-run opt-in 仅出 JSON plan 预览). 与 cortex-extract (L4-inbox 内部) 互补.