shfmt
Format and lint shell scripts
TLDR
Format shell script
SYNOPSIS
shfmt [-w] [-d] [-i indent] [-ln language] [options] [files]
DESCRIPTION
shfmt formats shell scripts. It parses and rewrites scripts with consistent styling, similar to gofmt for Go or prettier for JavaScript.
The tool understands multiple shell dialects: POSIX sh, bash, mksh, and bats. Detection is automatic from shebang or can be specified explicitly. Different dialects support different syntax.
Indent options control spacing: -i 2 for two spaces, -i 4 for four, -i 0 for tabs. Consistent indentation is the most impactful formatting change.
Write mode (-w) modifies files in place. Diff mode (-d) checks formatting without changing, useful in CI to enforce style. The exit code indicates whether formatting was needed.
The simplify option (-s) removes unnecessary syntax: unneeded quotes, redundant semicolons, POSIX-compatible alternatives. This produces cleaner, more portable code.
Minify mode (-mn) removes all non-essential whitespace, useful for embedded scripts or size-constrained environments.
PARAMETERS
-w, --write
Write result to file instead of stdout.-d, --diff
Show diff and exit with error if not formatted.-l, --list
List files that differ from formatted.-i N, --indent N
Indent spaces (0 for tabs).-ln LANG, --language-dialect LANG
Shell variant: bash, posix, mksh, bats.-bn, --binary-next-line
Binary operators start new lines.-ci, --case-indent
Indent case statement bodies.-sr, --redirect-operators
Redirect operators follow next line.-fn, --func-next-line
Function brace on next line.-kp, --keep-padding
Keep column alignment padding.-s, --simplify
Simplify code.-mn, --minify
Minify output.-f, --find
Find shell files recursively.--apply-ignore
Apply .shfmtignore files.
CAVEATS
May change script behavior in edge cases. Some heredoc formatting can be tricky. Not all style preferences are configurable. Parser may reject valid but unusual syntax. Backup files before mass formatting.
HISTORY
shfmt was created by Daniel Martà (mvdan) around 2016. Written in Go, it was inspired by gofmt's approach to code formatting. The project fills a gap - while other languages have standard formatters, shell scripts traditionally lacked one. It's widely adopted in CI pipelines and editor integrations.
SEE ALSO
shellcheck(1), bash(1), sh(1), prettier(1)
