这个项目能做什么
sh 是一个用纯 Go 编写的 shell 解析器、格式化工具和解释器,支持 POSIX Shell、Bash、Zsh 和 mksh。它需要 Go 1.26 或更高版本。
该项目分为三个主要包。syntax 包将 shell 脚本解析为语法树,允许像 shfmt 那样进行检查和格式化。shell 包提供具有 shell 语义的一站式辅助函数:将命令行拆分为参数并重新引用它们(类似于 shlex)、在字符串中展开 $VAR 和 ~,以及使用 ** 进行 glob 匹配或匹配 case 风格的模式。interp 包无需系统 shell 即可运行 shell 脚本,包括在 Windows 上;其处理器允许对脚本可以执行和访问的内容进行沙箱隔离。
shfmt 是该项目中使用最广泛的部分。它格式化 shell 程序,可通过 `go install mvdan.cc/sh/v3/cmd/shfmt@latest` 安装。典型用法是 `shfmt -l -w script.sh`。其默认风格由 syntax/canonical.sh 展示,并提供了 manpage。软件包通过多种渠道分发,包括 Alpine、Arch、Debian、Docker、Fedora、FreeBSD、Homebrew、MacPorts、NixOS、OpenSUSE、PyPI、Scoop、Snapcraft、Void 和 webi。Docker 镜像针对发布标签发布,`v3` 表示最新稳定版,`latest` 表示开发版;镜像仅包含 shfmt,并提供 Alpine 变体。
已记录的注意事项包括:在为 Bash 关联数组建立索引时必须加引号,因为静态解析器否则会假定为算术表达式;不支持 `$((` 与 `((` 的歧义,因为回溯会使解析器复杂化并阻止通过 io.Reader 进行流式处理;`export`、`let` 和 `declare` 被解析为关键字,以实现静态语法树并支持 `declare foo=(bar)` 等形式;并且由于该库是纯 Go 的,解释器无法完全匹配 POSIX Shell 和 Bash 的语义,例如子 shell 使用 goroutine 而非 fork 的进程,因此不会直接使用真实的 PID 和文件描述符。
格式化常见问题指出,无法对行范围禁用格式化,尽量避免新增格式化选项,并且重视一致性胜过满足每一种个人风格偏好。
一个名为 sh-syntax 的第三方 npm 包捆绑了解析器和格式化工具的 WASM 构建;较旧的基于 GopherJS 的 mvdan-sh 包已归档。列出的编辑器和工具集成包括 BashSupport-Pro、dockerfmt、intellij-shellscript、micro、neoformat、vscode-shfmt、shfmt.el、Trunk、modd、prettier-plugin-sh、sh-checker、mdformat-shfmt、pre-commit-shfmt 和 tesh。README 还指出,除非贡献者是活跃用户或贡献者,否则顺手的 AI 补丁没有帮助,并请求提供详细的问题报告。
评论
0 评分人数达到10人后显示
登录后参与讨论。