| name | shfmt-configuration |
| user-invocable | false |
| description | Use when configuring shfmt for shell script formatting including .shfmt.toml setup, EditorConfig integration, and project-specific settings. |
| allowed-tools | ["Read","Write","Edit","Bash","Grep","Glob"] |
shfmt Configuration
Master shfmt configuration for consistent shell script formatting across projects, including configuration files, EditorConfig integration, and team standardization.
Overview
shfmt is a shell parser, formatter, and interpreter that supports POSIX Shell, Bash, and mksh. Configuration allows you to define consistent formatting rules for your shell scripts.
Configuration Methods
shfmt supports multiple configuration approaches, in order of precedence:
- Command-line flags (highest precedence)
- EditorConfig settings
.shfmt.toml or shfmt.toml file
TOML Configuration File
Basic Configuration
Create .shfmt.toml or shfmt.toml in your project root:
shell = "bash"
indent = 2
binary-next-line = true
switch-case-indent = true
space-redirects = false
keep-padding = false
func-next-line = false
Configuration Options Explained
shell
Specifies the shell dialect for parsing:
shell = "posix"
shell = "bash"
shell = "mksh"
shell = "bats"
Auto-detection based on shebang if not specified:
#!/bin/sh -> posix
#!/bin/bash or #!/usr/bin/env bash -> bash
#!/bin/mksh -> mksh
indent
Controls indentation style:
indent = 2
indent = 4
indent = 0
binary-next-line
Controls binary operator positioning:
binary-next-line = false
if [ "$a" = "foo" ] &&
[ "$b" = "bar" ]; then
echo "match"
fi
binary-next-line = true
if [ "$a" = "foo" ] \
&& [ "$b" = "bar" ]; then
echo "match"
fi
switch-case-indent
Controls case statement indentation:
switch-case-indent = false
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
esac
switch-case-indent = true
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
esac
space-redirects
Controls spacing around redirections:
space-redirects = false
echo "hello" >file.txt
cat <input.txt
space-redirects = true
echo "hello" > file.txt
cat < input.txt
keep-padding
Preserves alignment padding:
keep-padding = false
short="value"
longer_var="another"
short="value"
longer_var="another"
keep-padding = true
short= "value"
longer_var="another"
func-next-line
Controls function brace placement:
func-next-line = false
my_function() {
echo "hello"
}
func-next-line = true
my_function()
{
echo "hello"
}
EditorConfig Integration
shfmt respects EditorConfig settings. Create or update .editorconfig:
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.sh]
indent_style = space
indent_size = 2
shell_variant = bash
binary_next_line = true
switch_case_indent = true
space_redirects = false
keep_padding = false
function_next_line = false
EditorConfig Option Mapping
| shfmt flag | EditorConfig key |
|---|
-i | indent_size (0 for tabs) |
-ln | shell_variant |
-bn | binary_next_line |
-ci | switch_case_indent |
-sr | space_redirects |
-kp | keep_padding |
-fn | function_next_line |
Command-Line Flags
Basic Usage
shfmt -w script.sh
shfmt -d script.sh
shfmt -l .
shfmt script.sh
Formatting Options
shfmt -i 4 script.sh
shfmt -i 0 script.sh
shfmt -ln bash script.sh
shfmt -bn script.sh
shfmt -ci script.sh
shfmt -sr script.sh
shfmt -kp script.sh
shfmt -fn script.sh
Combined Example
shfmt -i 2 -ci -bn -w script.sh
Project Configuration Patterns
Minimal Bash Project
shell = "bash"
indent = 2
POSIX-Compliant Scripts
shell = "posix"
indent = 4
binary-next-line = false
switch-case-indent = false
Modern Bash with All Features
shell = "bash"
indent = 2
binary-next-line = true
switch-case-indent = true
space-redirects = false
func-next-line = false
Team Standardization
shell = "bash"
indent = 2
binary-next-line = true
switch-case-indent = true
keep-padding = false
CI/CD Integration
GitHub Actions
name: Shell Format Check
user-invocable: false
on: [push, pull_request]
jobs:
shfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install shfmt
run: |
curl -sS https://webinstall.dev/shfmt | bash
export PATH="$HOME/.local/bin:$PATH"
- name: Check formatting
run: shfmt -d .
Pre-commit Hook
repos:
- repo: https://github.com/scop/pre-commit-shfmt
rev: v3.8.0-1
hooks:
- id: shfmt
args: ["-w"]
Makefile Target
.PHONY: fmt-check fmt
fmt-check:
shfmt -d .
fmt:
shfmt -w .
Best Practices
- Commit Configuration - Always commit
.shfmt.toml for team consistency
- Match Dialect - Set
shell to match your script shebangs
- EditorConfig First - Use EditorConfig for IDE integration
- CI Enforcement - Run
shfmt -d in CI to catch formatting issues
- Consistent Indentation - Pick 2 or 4 spaces and stick with it
- Document Choices - Add comments explaining non-default options
- Version Lock - Pin shfmt version in CI for reproducibility
Troubleshooting
Configuration Not Applied
Check precedence order:
- Command-line flags override everything
- EditorConfig in file's directory
.shfmt.toml in project root
Wrong Shell Dialect
Verify shebang matches configuration:
EditorConfig Not Detected
Ensure EditorConfig file is in parent directory chain and has correct section:
[*.sh]
shell_variant = bash
When to Use This Skill
- Setting up shfmt in new projects
- Configuring team-wide formatting standards
- Integrating shfmt with CI/CD pipelines
- Troubleshooting configuration issues
- Migrating between configuration methods
- Setting up EditorConfig for shell scripts