sh is a shell parser, formatter, and interpreter written in Go that supports POSIX Shell, Bash, Zsh, and mksh.
The tool addresses the need to programmatically work with shell scripts in Go applications. It provides three main capabilities: parsing shell code into an abstract syntax tree through its syntax package, performing high-level operations like shell expansions through its shell package, and interpreting or executing shell scripts through its interp package. The shfmt command-line tool formats shell programs according to a canonical style, with options to list differences or write changes in place.
Developers should choose this tool when they need to integrate shell script processing into Go applications or want a standalone formatter for shell code. It suits projects that require parsing shell syntax without spawning external processes, or teams seeking consistent shell script formatting. The tool's pure Go implementation means it runs anywhere Go runs without external dependencies, though this design choice limits how closely the interpreter can follow POSIX and Bash semantics in edge cases like process forking and file descriptor handling. The formatter intentionally avoids partial-file formatting and minimizes configuration options to maintain consistency and reduce maintenance burden.
Development activity shows a disciplined approach to scope and quality. The project explicitly discourages drive-by patches from non-active contributors, requesting detailed issues instead. The maintainer has established clear caveats about parser limitations, such as the inability to handle certain ambiguities in Bash syntax without backtracking, and documents these transparently in the README. The project maintains a philosophy against adding formatting flags beyond necessity, acknowledging that each option multiplies complexity across development, testing, and documentation. The tool is packaged across numerous distributions and platforms, indicating sustained maintenance and broad compatibility testing.