mcpField
S
shfmt

shfmt

官方Agent-ready
github.com开发者工具9.2kshfmt1 天前更新
代码仓库访问官网

关于 shfmt

shfmt 对 Shell 脚本进行格式化和解析,应用一致的代码风格。支持多种 Shell 方言,可单独或批量格式化脚本文件。

主要功能

  1. 01格式化单个或多个 Shell 脚本
  2. 02自动修复 Shell 代码风格
  3. 03支持 POSIX 和 Bash 等多种 Shell 方言

适用场景

  1. 01维护团队 Shell 脚本的一致代码风格
  2. 02在自动化工作流中标准化脚本格式
  3. 03配合版本控制检查代码一致性

安装

选择你的系统或包管理器,复制命令到终端运行。

$
brew install shfmt

安装完成后运行shfmt --version确认安装成功。

命令示例

常用命令按使用顺序排列。

01
shfmt -w script.sh
02
shfmt -d .

详细介绍

sh

Go Reference

一个 Shell 解析器、格式化工具和解释器。 支持 POSIX Shell、Bash、Zsh 和 mksh。需要 Go 1.26 或更高版本。

快速开始

如需将 Shell 脚本解析为语法树、检查语法树, 并像 shfmt 一样格式化脚本, 请参阅 syntax package。

如需使用遵循 Shell 语义的单次调用辅助函数, 请参阅 shell package: 将命令行拆分为参数并像 shlex 一样重新引用参数、展开字符串中的 $VAR 和 ~,以及使用 ** 进行 glob 匹配或匹配 case 风格的模式。

如需在没有系统 Shell 的情况下运行 Shell 脚本(包括在 Windows 上), 请参阅 interp package; 其处理器可用于配置脚本可以执行的操作和访问的内容。

shfmt
go install mvdan.cc/sh/v3/cmd/shfmt@latest

shfmt 用于格式化 Shell 程序。有关其默认风格的快速概览,请参阅 canonical.sh。例如:

shfmt -l -w script.sh

如需了解更多信息,请参阅其 manpage,可直接以 Markdown 格式查看,也可使用 scdoc 渲染。

可通过 Alpine、Arch、Debian、Docker、Fedora、FreeBSD、 Homebrew、MacPorts、NixOS、OpenSUSE、PyPI、Scoop、Snapcraft、Void 和 webi 获取软件包。

赞助

如果这个项目为你或你的公司节省了时间,不妨考虑 在 GitHub 上赞助我。 月度赞助档位包含多种权益,例如在 README 中展示你的徽标、 优先处理问题,或在你公司的聊天应用中提供直接支持。 一次性赞助档位则可获得关于我的某个项目的交流机会, 或 Go 咨询与指导服务。

CI powered by Namespace

贡献

请将错误报告和功能请求提交为详细的问题, 最好附上能够复现错误或说明你期望功能的示例。

除非你是本项目的活跃用户或贡献者,否则临时提交的 AI 补丁并无帮助。请改为提交详细的问题。

注意事项
  • 索引 Bash 关联数组时,请始终使用引号。否则,静态解析器 只能假定索引是算术表达式。
$ echo '${array[spaced string]}' | shfmt
<standard input>:1:16: not a valid arithmetic operator: `string`
$ echo '${array[weird!key]}' | shfmt
<standard input>:1:8: reached `!` without matching `[` with `]`
$ echo '${array[dash-string]}' | shfmt
${array[dash - string]}
  • 不支持 $(( 和 (( 的歧义情况。回溯会让解析器更加复杂, 并使通过 io.Reader 实现流式处理成为不可能。如果 $( ( 表示该用法,POSIX 规范 建议在操作数之间加空格。
$ echo '$((foo); (bar))' | shfmt
1:1: reached ) without matching $(( with ))
  • export、let 和 declare 会被解析为关键字。 这样就能静态构建它们的语法树, 而不是将参数保留为单词切片。 这也是支持 declare foo=(bar) 的必要条件。

  • 整个库完全由 Go 编写,这限制了解释器遵循 POSIX Shell 和 Bash 语义的程度。 例如,Go 不支持派生自身进程,因此子 Shell 会改用 goroutine, 这意味着无法直接使用真实的 PID 和文件描述符。

格式化常见问题
  • 格式化工具无法针对某些行禁用格式化;大多数有此需求的用户 是在绕过错误,或是不喜欢某段代码的格式化效果。 因此,请先搜索问题跟踪器,必要时再提交新问题。 对部分文件进行格式化会带来许多边缘情况和复杂性, 而本项目既没有资源,也没有意愿去处理这些问题。

  • 我们尽可能避免添加更多格式化选项。每个新增的标志都会与其他标志相互影响, 从而成倍增加开发、维护、测试以及向最终用户准确记录行为所需的人力成本。

  • 格式化工具的真正价值在于保持一致性,尤其是对开发团队而言。 我们的目标并非满足每位开发者对理想格式的个人偏好。

JavaScript

解析器和格式化器可通过第三方 npm 包 sh-syntax 使用,该包包含一个编译为 WASM 的本库版本。

此前,我们维护过一个名为 mvdan-sh 的 npm 包,它使用 GopherJS 打包本库的 JS 版本。由于性能不佳且 GopherJS 的开发活跃度有所下降,该 npm 包现已归档。现有用户和新用户都应改用 sh-syntax。

Docker

所有发布标签都会通过 Docker 发布,例如 v3.5.1。 目前,最新的稳定版以 v3 发布,最新的开发版以 latest 发布。 镜像仅包含 shfmt;Alpine Linux 上还提供 -alpine 变体。

要构建 Docker 镜像,请运行:

docker build -t my:tag -f cmd/shfmt/Dockerfile .

要使用 Docker 镜像,请运行:

docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/mnt" -w /mnt my:tag <shfmt arguments>
相关项目

以下编辑器集成封装了 shfmt:

其他值得关注的集成包括:

评论

支持 Markdown