关于 shell-snippet-fmt
shell-snippet-fmt 是一项用于规范 Shell 代码片段格式的技能,旨在保持可读性并避免改变命令行为。它规定每行不超过 120 列,并说明长命令的安全换行方式。
主要功能
- 01每行最多 120 列
- 02命令的安全续行位置
- 03引号字符串与 heredoc 规则
- 04文档和脚本中的格式指南
适用场景
- 01整理文档中的长 Shell 命令
- 02编辑含超长命令行的脚本
- 03检查聊天或差异中的 Shell 片段
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ petr-korobeinikov/ skills --skill shell-snippet-fmt安装后在 Claude Code 中输入/shell-snippet-fmt确认已加载。
详细介绍
shell-snippet-fmt
始终对 shell 代码片段进行格式化,确保每行不超过 120 列。
如果某行将超过此限制,
请在安全的位置换行,并在行尾添加 \。
原因
120 列的上限能让代码片段在窄终端、
GitHub 差异视图、
并排审阅窗格
和聊天窗口中都易于阅读。
显式使用 \ 续行是唯一一种可移植的方式,可在不改变 shell
命令语义的情况下换行 —
shell 会原样保留引号字符串和 heredoc 中的空白,
因此在这些位置换行会改变程序行为。
规则
- shell 代码片段的每一行都应保持 ≤120 个视觉列宽 (每个字符占一列,不论字节宽度)。
- 如果某行将超过此限制,
请在仍能符合限制的最靠后安全位置换行,
并在行尾添加
\。 \后面不能有任何内容 — 甚至不能有空格或注释; 只能是换行符。- 续行相对于命令起始位置缩进 4 个空格。
- 如果代码片段本来就能在 120 列以内放在一行, 可以保持单行, 也可以在多行形式更清晰时换行 (复杂管道、多个标志、heredoc、短参数之间的长 URL)。 可读性优先于紧凑性; 120 列是硬性上限,而非目标。
安全的换行位置
只能在 shell 仍会将结果解析为一个逻辑命令的位置换行:
- 在标志前(
--flag或-f value)。 - 在管道符前(
|)。 - 在逻辑运算符前(
&&、||)。 - 在重定向符前(
>、>>、<、2>&1)。 - 在位置参数之间, 前提是每个参数都是独立的词元。
绝不能在以下位置换行
- 引号字符串内部 —
在
'...'中,\<newline>会按字面内容保留 (单引号不会解释转义符), 因此打印出的文本会多出一个反斜杠和换行符; 在"..."中,POSIX 会将\<newline>视为续行符 并静默移除两者, 将前后文本拼接在一起。 无论哪种情况,呈现的字符串都会与单行版本不同。 - heredoc 正文内部(从开头的
<<EOF到结束标记之间) — 内容会原样传递给命令, 因此插入的\<newline>会成为数据的一部分。 - 未加引号的词元内部 — 拆分会改变词边界。
- URL、 路径、 标识符 或任何其他不可拆分的单元内部。
如果一个不可拆分的词元本身就超过 120 列, 请保留超限行, 并在周围文本中注明此例外, 让读者知道这是有意放宽上限。
示例
错误 — 单行长达 138 列:
docker run --rm -it --name foo -v "$PWD:/work" -w /work -e FOO=bar -e BAZ=qux ghcr.io/example/tool:1.2.3 build --target prod --output dist
正确 — 使用 \ 换行,每行均 ≤120 列:
docker run --rm -it --name foo \
-v "$PWD:/work" \
-w /work \
-e FOO=bar \
-e BAZ=qux \
ghcr.io/example/tool:1.2.3 \
build --target prod --output dist
接下来的三个示例(管道符、逻辑运算符、heredoc)保持简短, 以便清楚展示换行约定 — 仍应遵循“仅在有助于可读性时换行”的规则, 但在需要换行时应采用以下形式。
管道符放在续行的行首,
并在前一行末尾使用 \:
curl -sSL https://example.com/data.json \
| jq '.items[]' \
| head -20
逻辑运算符遵循相同的约定:
docker build -t image:tag . \
&& docker push image:tag \
&& echo "deployed"
heredoc — 换行处理周围的命令,
heredoc 正文保持原样(不添加 \,保留原始行):
ssh -o ConnectTimeout=10 \
-o StrictHostKeyChecking=no \
deploy@host bash <<'EOF'
cd /app
./run --restart
EOF
错误 — 在 \ 和换行符之间添加注释会中断续行:
docker run \ # mount the work dir
-v "$PWD:/work" image
\ 后面跟着空格和 #,而不是换行符,
因此 shell 会停止续行,
并将下一行的 -v 解析为单独的命令。
请将注释放在命令上方的独立行中,
切勿放在行尾的 \ 后面。
错误 — 在引号字符串内部换行会改变程序输出:
echo 'this is a very long error message that needs to clearly demonstrate \
exceeding the 120-character width limit when written on one line'
在单引号中,\<newline> 会按字面内容打印为 \ + 换行符;
在双引号中,POSIX 会将其移除并拼接相邻文本 —
无论哪种情况,结果都与单行版本不同。
即使行长超过 120 列,也要保持字符串完整:
echo 'this is a very long error message that needs to clearly demonstrate exceeding the 120-character width limit when written on one line'
长的不可拆分词元(URL、路径、哈希)同理:
curl -O https://github.com/very-long-org-name/very-long-repo-name/releases/download/v1.2.3-rc.4/binary-name-linux-amd64.tar.gz
请在周围文本中注明超限行,让读者知道这是有意放宽了上限。
适用范围
适用于你编写或编辑的任何 shell 片段:
- 聊天回复中的围栏代码块。
SKILL.md/README.md/ 文档中的代码片段。scripts/下的脚本。- Makefile 配方。
- CI 配置(GitHub Actions 的
run:、GitLab 的script:)。 - Dockerfile 的
RUN指令。 - 安装说明和单行命令。
如果编辑文件时遇到很长且未换行的命令, 请在同一次编辑中对其重新排版。