About this project

sh is a shell parser, formatter and interpreter written in pure Go, supporting POSIX Shell, Bash, Zsh and mksh. It requires Go 1.26 or later. The project is organized into three main packages. The syntax package parses shell scripts into a syntax tree, allowing inspection and formatting in the same way shfmt does. The shell package offers one-call helpers with shell semantics: splitting a command line into arguments and quoting them back (similar to shlex), expanding $VAR and ~ inside strings, and globbing with ** or matching case-style patterns. The interp package runs shell scripts without a system shell, including on Windows; its handlers allow sandboxing what scripts may execute and access. shfmt is the most widely used part of the project. It formats shell programs and can be installed via `go install mvdan.cc/sh/v3/cmd/shfmt@latest`. Typical usage is `shfmt -l -w script.sh`. Its default style is illustrated by syntax/canonical.sh, and a manpage is provided. Packages are distributed through many channels, including Alpine, Arch, Debian, Docker, Fedora, FreeBSD, Homebrew, MacPorts, NixOS, OpenSUSE, PyPI, Scoop, Snapcraft, Void and webi. Docker images are published for release tags, with `v3` for the latest stable and `latest` for development; images contain only shfmt, with Alpine variants available. Documented caveats include: quoting is required when indexing Bash associative arrays, since the static parser otherwise assumes an arithmetic expression; the `$((` versus `((` ambiguity is not supported because backtracking would complicate the parser and prevent streaming via io.Reader; `export`, `let` and `declare` are parsed as keywords to enable static syntax trees and support forms like `declare foo=(bar)`; and because the library is pure Go, the interpreter cannot fully match POSIX Shell and Bash semantics, for example subshells use goroutines rather than forked processes, so real PIDs and file descriptors are not used directly. Formatting FAQs state that formatting cannot be disabled for line ranges, that new formatting options are avoided where possible, and that consistency is valued over satisfying every personal style preference. A third-party npm package called sh-syntax bundles a WASM build of the parser and formatter; the older GopherJS-based mvdan-sh package is archived. Editor and tool integrations listed include BashSupport-Pro, dockerfmt, intellij-shellscript, micro, neoformat, vscode-shfmt, shfmt.el, Trunk, modd, prettier-plugin-sh, sh-checker, mdformat-shfmt, pre-commit-shfmt and tesh. The README also notes that drive-by AI patches are not helpful unless the contributor is an active user or contributor, and asks for detailed issues instead.