HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
mvdan
sh
Go2016–2025
mvdan / sh

sh

A shell parser, formatter, and interpreter with bash and zsh support; includes shfmt

20Distinct people
30Mentions
1Explicit recommenders
9.2KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A shell parser, formatter, and interpreter with bash and zsh support; includes shfmt

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

This is one of my favorite tips for almost effortlessly improving devops productivity (along with using https://github.com/mvdan/sh for auto-formatting) — by now shellcheck has…

acdha used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year30 dated mentions

Observed mentions: 2016-06-04 20:55:06 UTC to 2025-04-09 05:06:59 UTC.

024682016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 8 mentions; 7 submissions, 1 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 6 mentions; 2 submissions, 4 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC871
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC000
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC000
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC110
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC312
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC707
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC211
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC624
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101

What Hacker News says

30 sources
I use `mvdan/sh` [1] under the hood for processing the commands. So it will reformat if [ foo ] ; then bar fi to if [ foo ] then bar fi And also format your example to foo bar In this type of situation, it becomes a little trickier to disambiguate when I need to add semicolons and a backslash, and when I need to add only backslashes. If you use `&&` -- you have disambiguated the two cases so I can format it. [1] https://github.com/mvdan/sh
In Dockerfmt: A Dockerfile Formatter

Show HN: Hucksh – A shell with a very good memory

In the deep mists of time (circa 2012), I was playing with the Go standard library, and saw how easy it was to stand up a webserver that let you navigate a remote file system, and I thought it was pretty neat. I took a look at my shell history and a frequent pattern of commands was "cd, ls, cd, ls, ...". And I thought "I love my keyboard, but you know, point and click might be nice in this context." And then I thought, "It'd be even cooler if you could run commands there." Skip forward several years, a few earlier implementations, a name change, and now there's Hucksh(ell), a bash-like shell that makes it easy to do all that. There's a directory navigation tab, where you can click around to navigate, use forward and back buttons (like a browser), and also a "navigate" mode where you can select the directory to change to with a single keys
Read the rest
troke. The system remembers every directory you do anything in and lets you choose them from a list, which you can order by name, time last used, or frequency of use. And finally, of course, there are shell tabs where you can run individual commands. Each command gets its own widget in the UI, separate from the others, in its own tty, with no overlap. The system saves each command you run, along with its start & stop times, the directory you were in, the result code when it finishes, and (this is the fun part) the command output, all in a sqlite database, on disk. (Disk is cheap, yeah? Might as well do something with it.) This allows you to do some neat things with history and context. * Keep the same tab open forever, maintaining months or years of context and history * Pick up where you left off a month or a year ago * Pick up where you left off after a system restart (like when you restart your browser and it reopens all your windows and tabs) * Review everything you've done in a project directory * Review everything you did yesterday, or a month ago I hope in the future to make it easy to share history, which could help with new employee onboarding, teaching, asking or answering questions on StackOverflow, documenting a penetration test, or anywhere else you want to easily share your work or consume someone else's work. Everything is in Go. * The front-end uses Gio UI, a cross-platform GUI for Go * The shell itself is https://github.com/mvdan/sh, a bash-like command interpreter * The terminal emulator is a fork of Darktile (https://github.com/liamg/darktile) with very few changes. This is not a SaaS. You download code and run the front- and back-end yourself, like ssh/sshd. (Except it doesn't run as root.) This is a commercial product. Without a license, the app limits you to a single top-level window, with two shell tabs. (Similar to a single iTerm window with two tabs.) With a license, as many windows and tabs as you like. I'm looking for any kind of feedback whatsoever, positive or negative, from the app itself, to the documentation and other online information, to this very post. hucksh is currently available for macOS and Linux. Learn more: https://huckridge.notion.site/Hucksh-overview-2fdcaf7d639145... Download, etc: https://huckridge.notion.site/Hucksh-online-download-purchas...
93 points · Open discussion
> I always expected to become fluent in bash at some point, but the AI became too good at writing my scripts now... This page : https://mywiki.wooledge.org/BashPitfalls Is the fastest way of becoming proficient with shell scripting. Whether it's pure posix shell, or bash and its extensions, they're small languages and can be learned in a week end if you're proficient in another programming language. The main pain point is that there's a lot of "surprises" and non-intuitive behaviors, that are all listed here. The first ones, about parameter expansions, quoting variables and leading dashes are the most common issue with newbies in shell scripting. There's a lot of amazing tooling these days to make sure your shell scripts are fine too. First, shellcheck: https://www.shellcheck.net/ I systematically run this on my scripts before using them.
Read the rest
Then shfmt for nice, reliable autoformatting: https://github.com/mvdan/sh And finally, checkbashisms if you intend on making pure posix scripts that are compatible with debian/ubuntu's dash. It is part of the debian's devscripts suite, but is often individually packaged in other distros. > Also you can use the chat as a learning tool Or you could learn from a guide written by people who have suffered decades of experience of the pitfalls of shell scripting and have shared their woes. https://mywiki.wooledge.org/BashGuide chatGPT is good at coming up with magical solutions, but teaching you about all the corner cases?
In Pure Bash Bible (2018)
For the first two caveats, I actually agree that we could and should handle ambiguous input. It just hasn't been a priority because doing that properly would be quite a bit of work, and such ambiguous syntax isn't particularly common. See https://github.com/mvdan/sh/issues/686 for my current thoughts on how to tackle it. The third caveat concerns parsing `export` and `let` as keywords rather than as builtins. Like the README says, this is to properly build the syntax tree without leaving opaque strings as expressions, but also to support `declare foo=(bar)` which wouldn't work if `declare` was treated like any other builtin simple command. How else would you have a static parser handle these two builtins? They are in a bit of an awkward middle ground between builtin and keyword. My instinct is that giving them special treatment in the par
Read the rest
ser to allow tokens like `(`, while at the same time representing them in the syntax tree with opaque strings as expressions, would be pretty underwhelming to any users of the parser. That said, we already have that problem with `let "foo=123"` for example, where our parser currently represents the expression as the quoted string without going any deeper. https://github.com/mvdan/sh/issues/754#issuecomment-96329574... considers doing a second parse stage in the shell interpreter to fix cases like these, though always doing a second parse could get expensive. We _could_ leave all arithmetic expressions as input strings in the parser, and do all the actual parsing when they are evaluated. That would be more compatible with Bash and more consistent. But it would also be less useful to any parser users who don't run into any of these weird edge cases, which aren't common at all, I think. In short, I have some ideas, but I'm not sure at all what's best :) Doing a good job for 99% of users feels better than aiming for 100% compatibility with bash syntax, particularly where bash syntax is a bit weird.
In Shfmt – format shell programs
See also: interfacer - Automatically Suggest Interface Types in Go https://github.com/mvdan/interfacer https://news.ycombinator.com/item?id=11397905 (9 comments) shmfmt - A shell parser, formatter, and interpreter with BASH support https://github.com/mvdan/sh (Submitted often but not yet discussed) --- /me whispers: Hint: You could be that guy [1] (or gal, they, it, etc): /submit shmfmt Feel free to leave a link to your submission here for other inquisitive parties to stumble upon. [1] https://youtube.com/watch?v=HQXTxG8JBAw&t=105s Transparency: Clip is mildly offensive
In Gofumpt: A stricter gofmt
Not one-liners, but some of the tools that I have found helpful for working with large bash codebases are: - shellcheck and shfmt for linting and formatting - sub for organizing subcommands - bashdb for debugging scripts interactively via the VSCode extension I'm still missing a way to share modules with others like it can be done with ansible/terraform, but I have not found an optimal way to do it yet. [shellcheck] https://github.com/koalaman/shellcheck [shfmt] https://github.com/mvdan/sh [sub] https://github.com/qrush/sub [bashdb] http://bashdb.sourceforge.net/ [vscode-bash-debug] https://github.com/rogalmic/vscode-bash-debug
In Bash-oneliner: A collection of handy Bash one-liners and terminal tricks
a-t-0·Feb 20, 2022Submission

Ask HN: Let's build Checkstyle for Bash?

After working with Bash and Shellcheck for a few months, I noticed I could improve my code quality by making it compliant with the Shell Style Guide by Google [0]. While working on that, I thought some aspects of this Shell style guide can be verified automatically, granted some assumptions/opinions are formed. So I looked around for linting tools and autoformatters for Bash: Shellcheck: https://github.com/koalaman/shellcheck From Asynchronous Lint Engine (ALE): https://github.com/dense-analysis/ale/blob/master/supported-... - bashate: https://github.com/openstack/bashate - cspell: https://github.com/streetsidesoftware/cspell/tree/main/packa... - Bash Language Server: https://github.com/bash-lsp/bash-language-server - shell -n flag: https://www.gnu.org/software/bash/manual/bash.html#index-set - sh(shfmt): https://github.com/mvdan/sh - shd
Read the rest
oc: https://github.com/reconquest/shdoc From this stack post [1]: - checkbashisms: http://man.he.net/man1/checkbashisms - shlint: https://github.com/duggan/shlint (archived) Prettier: https://marketplace.visualstudio.com/items?itemName=esbenp.p... Within all these linters and auto-formatters I did not find checks that enforce, for example, the Function Comments of the Shell Style Guide by Google: All function comments should describe the intended API behaviour using: Description of the function. Globals: List of global variables used and modified. Arguments: Arguments taken. Outputs: Output to STDOUT or STDERR. Returns: Returned values other than the default exit status of the last command run. Hence, I thought we could make a Bash linting tool that verifies compliance with the Shell Style Guide by Google. To do so, a brief start was made here [2]. It identifies/lists elements in that style guide that may be verified automatically. Since Bash has been around longer than me, I think there may be some people better suited for the development of this enhanced linter. Hence, I thought it might be wise, for impact and usability, to share this idea here. What do you say, HN? [0]: https://google.github.io/styleguide/shellguide.html [1]: https://stackoverflow.com/questions/3668665/is-there-a-stati... [2]: https://github.com/TruCol/checkstyle-for-bash
59 points · Open discussion
Some other shell script check and formatting tools: All shells take the -n option to perform a basic syntax check. Debian has a script for checking scripts for bashisms: https://manpages.debian.org/checkbashisms bashate is a automated style checker for bash (similar to pep8 for python): https://opendev.org/openstack/bashate lintshell is an early prototype of a shell linter based on the Morbig trustworthy static parser for POSIX shell, based on the Why3 platform for deductive program verification. https://www.irif.fr/~treinen/colis/ https://github.com/colis-anr/morbig https://github.com/colis-anr/lintshell Shellharden helps rewrite scripts for ShellCheck compliance: https://github.com/anordal/shellharden/ shfmt is gofmt for shell: https://github.com/mvdan/sh ShellScriptFormatter is another formatter: https://github.com/osalvador/ShellScrip
Read the rest
tFormatter Some of these tools and other tools can be automatically run by check-all-the-things: https://github.com/collab-qa/check-all-the-things/
In ShellCheck: Finds bugs in your shell scripts
This is really cool and having spoken with the lead dev, Kenneth, I trust that this will continue to be well supported. This is built on tree-sitter, but there are a couple of other interesting shell parser projects: * https://github.com/mvdan/sh * https://github.com/koalaman/shellcheck At Fig (https://withfig.com), we had to write a bash parser from scratch. These projects all work well in the IDE context, but in a repl environment (ie when typing in your terminal) they don't support incomplete commands very well. e.g if I type `echo "$(` the above parsers will break as the double quote and parentheses are not closed.
In Bash-LSP: A language server for Bash

Showing the 15 most recent of 30 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.