plugins/languages/bash/skills/posix/SKILL.md
POSIX sh portability guidance: when to choose /bin/sh vs /usr/bin/env bash, dash/ash vs bash feature matrix, macOS bash 3.2 legacy constraints, busybox/Alpine ash quirks, portable replacements for [[ ]] / arrays / process substitution, and shellcheck -s sh enforcement. Use when targeting Alpine containers, OpenWrt, BSD systems, init scripts, or any environment without bash. Triggers on "POSIX sh", "/bin/sh", "dash", "ash", "busybox shell", "macOS bash 3.2", "alpine 脚本", "可移植脚本".
npx skillsauth add lazygophers/ccplugin bash-posixInstall 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.
| 场景 | 推荐 |
|------|------|
| Alpine / busybox 容器 init | POSIX sh (#!/bin/sh) |
| OpenWrt / 路由器 / 嵌入式 | POSIX sh |
| Debian / Ubuntu 启动脚本(dash) | POSIX sh |
| macOS 用户脚本(系统 bash 3.2) | Bash 4+(明确依赖)或 POSIX sh |
| 现代 Linux 桌面 / 服务器 | Bash 5.2+ |
| 项目内工具脚本 | Bash 5.2+(明确版本) |
原则:默认 Bash,只在跨极简环境时降级 POSIX。降级前评估是否能换 brew/apk 装 bash。
| Bash | POSIX sh 替代 |
|------|--------------|
| [[ str == pat ]] | case "$str" in pat) ;; esac |
| [[ str =~ regex ]] | echo "$str" \| grep -Eq 'regex' |
| (( a > b )) | [ "$a" -gt "$b" ] |
| arr=(a b c) | 位置参数 set -- a b c |
| ${arr[@]} | "$@" |
| ${var,,} / ${var^^} | tr '[:upper:]' '[:lower:]' |
| local | 无;用函数命名空间或 subshell |
| $'...' | printf '%b' '...' |
| <(cmd) 进程替换 | 管道 / 临时文件 |
| mapfile -t a < f | while IFS= read -r line; do ...; done < f |
| read -p prompt | printf '%s' prompt; read var |
| echo -e | printf '%b\n' |
| ${var:-x} | 可用(POSIX) |
| ${var/from/to} | echo "$var" \| sed 's/from/to/' |
| 关联数组 declare -A | 多变量前缀或 awk |
macOS 因许可证未升级,系统 /bin/bash 仍是 3.2.57 (2007):
declare -A)${var,,} / ${var^^} 大小写[[ -v var ]](检查是否定义)mapfile / readarraywait -n${var@Q} 参数转换<(...) 有但 macOS sandbox 可能限制应对策略:
(( BASH_VERSINFO[0] >= 4 )) || { echo "need bash 4+" >&2; exit 1; }#!/usr/bin/env bash 由 PATH(brew install bash → /opt/homebrew/bin/bash)解析。# 检查 bash 主版本
need_bash() {
if [[ -z "${BASH_VERSION:-}" ]]; then
echo "error: this script requires bash, not sh" >&2
exit 1
fi
local major="${BASH_VERSINFO[0]}"
if (( major < 4 )); then
echo "error: bash >= 4 required (have ${BASH_VERSION})" >&2
exit 1
fi
}
POSIX 检测自身:
# POSIX 不能用 BASH_VERSION(dash 中未定义且 set -u 触发)
if [ -n "${BASH_VERSION:-}" ]; then
echo "running on bash"
fi
#!/bin/sh
# brief: portable script
set -eu
# pipefail 不可用;按需手动 wait
log() { printf '%s\n' "$*" >&2; }
die() { log "fatal: $*"; exit 1; }
# 位置参数代替数组
process_all() {
[ $# -gt 0 ] || die "no args"
for item in "$@"; do
printf 'item=%s\n' "$item"
done
}
# case 代替 [[ == ]]
case "${1:-}" in
*.txt) log "text" ;;
*.md) log "markdown" ;;
*) die "unknown ext" ;;
esac
# 算术
n=10
if [ "$n" -gt 5 ]; then
log "big"
fi
# 字符串小写
lower=$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')
process_all "$@"
shellcheck -s sh script.sh # 强制 POSIX
shellcheck -s bash script.sh # bash 模式
shellcheck -s dash script.sh # dash 模式(Debian /bin/sh)
# 文件内声明(推荐)
# shellcheck shell=sh
local 在 ash 中可用(虽非 POSIX 标准)。echo -e 在 ash 中默认行为不同;统一 printf。command -v ? 实际上有,是 POSIX 标准;放心用。/bin/sh)shellcheck -s sh[[ ]] / 数组 / == / <() / (( )) 出现在 POSIX 脚本/bin/sh 而非 /bin/bashtools
--- 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 内部) 互补.