sh

repository·master·Indexed 27 days ago

https://github.com/mvdan/sh

A comprehensive shell parser, formatter, and interpreter written in pure Go. It supports POSIX Shell, Bash, Zsh, and mksh. The project includes the shfmt command-line tool for formatting shell programs, the gosh proof-of-concept shell, and a Go library with packages for syntax parsing, shell expansion, and interpretation. It is also available as a WASM-based npm package called sh-syntax.

Tokens
2.4K
Snippets
9
Records
20
Agent score
86%

What's inside sh

  1. Use the sh library for parsing, expansion, and interpretation

    master

    The sh library provides tools for working with shell scripts in Go. Depending on your goal, use the following packages:

    • Parsing and Inspection: Use the syntax package to parse shell scripts and inspect their structure.
    • Shell Expansions: Use the shell package for high-level operations like performing shell expansions on strings.
    • Interpretation: Use the interp package to interpret or run shell scripts.
  2. Use shfmt via Docker

    master

    Release tags are published to Docker. The v3 tag represents the latest stable release, and latest represents the latest development version. Images only include shfmt (with -alpine variants available).

    To build a custom Docker image:

    docker build -t my:tag -f cmd/shfmt/Dockerfile .

    To run shfmt using a Docker image, mount your current directory and run the command:

    docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/mnt" -w /mnt my:tag <shfmt arguments>
    docker build -t my:tag -f cmd/shfmt/Dockerfile .
    docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/mnt" -w /mnt my:tag <shfmt arguments>
  3. Use sh-syntax in JavaScript via WASM

    master

    The parser and formatter are available as an npm package called sh-syntax. This package bundles a version of the library compiled to WebAssembly (WASM).

    Note: The older mvdan-sh package (which used GopherJS) is archived and should not be used.

  4. Install gosh (Proof of Concept Shell)

    master

    gosh is a proof-of-concept shell that demonstrates the usage of the interp package. Install it via Go:

    go install mvdan.cc/sh/v3/cmd/gosh@latest
    go install mvdan.cc/sh/v3/cmd/gosh@latest
  5. Install and use shfmt to format shell programs

    master

    shfmt is a command-line tool for formatting shell programs. You can install it using Go:

    go install mvdan.cc/sh/v3/cmd/shfmt@latest

    To format a file in-place and list the files that were changed, use the -l and -w flags:

    shfmt -l -w script.sh

    shfmt is also available via various package managers including Homebrew, Debian, Arch, and others.

    go install mvdan.cc/sh/v3/cmd/shfmt@latest
  6. Use shfmt to format shell programs

    master

    The shfmt CLI tool formats shell scripts. It accepts file paths as arguments. If no arguments are provided, or if - is used, it reads from standard input. If a directory is provided, it recursively processes all shell scripts found within.

    Note on EditorConfig: shfmt respects .editorconfig files for formatting options. However, if any parser or printer flags are explicitly passed via the CLI, the EditorConfig settings are ignored. You can force EditorConfig usage by providing a default flag like -i=0.

  7. Use the shfmt CLI to format shell programs

    master

    The shfmt command-line tool formats shell scripts. It can process files provided as arguments, directories (recursively), or standard input. If no arguments are provided or a dash (-) is used, it reads from stdin.

    Usage:

    shfmt [flags] [path ...]

    Key Behaviors:

    • Standard Input: If the only argument is - or no arguments are given, shfmt uses stdin. Note that -w (write) cannot be used with stdin.
    • Directories: If a path is a directory, all shell scripts found within it will be formatted.
    • EditorConfig: shfmt can read formatting options from .editorconfig files. However, providing any parser or printer flags via the CLI will disable EditorConfig settings for that execution.
    shfmt [flags] [path ...]
  8. Configure shfmt via EditorConfig

    master

    You can use an .editorconfig file to define formatting rules for shell scripts. Supported keys include:

    • indent_style and indent_size (maps to -i)
    • shell_variant (maps to -ln)
    • simplify (maps to -s)
    • binary_next_line (maps to -bn)
    • switch_case_indent (maps to -ci)
    • space_redirects (maps to -sr)
    • keep_padding (maps to -kp)
    • function_next_line (maps to -fn)
    • minify (maps to -mn)

    To ignore specific directories (e.g., third_party), use the ignore = true setting. Note that when formatting files directly (not via directory walking), you must use the --apply-ignore flag for these rules to take effect.

    [*.sh]
    indent_style = space
    indent_size = 4
    shell_variant = posix
    simplify = true
    binary_next_line = true
    switch_case_indent = true
    space_redirects = true
    keep_padding = true
    function_next_line = true
    minify = true
    
    [third_party/**]
    ignore = true
  9. Caveats and limitations of the sh parser

    master

    When using the parser, be aware of the following limitations:

    • Bash Associative Arrays: Always use quotes for indices containing spaces or special characters. Without quotes, the static parser assumes the index is an arithmetic expression and may fail.
    • Arithmetic Ambiguity: The parser does not support the ambiguity between $(( and ((. To avoid errors, follow the POSIX recommendation to space the operands (e.g., use $( ( instead of $(().
    • Keywords: export, let, and declare are parsed as keywords to support static syntax tree building (e.g., declare foo=(bar)).
    • Subshells: Because the library is written in pure Go and Go does not support forking its own process, subshells use goroutines instead of real processes. This means real PIDs and file descriptors cannot be used directly.
  10. Use shfmt for syntax checking

    master
    You can use shfmt as a more exhaustive alternative to bash -n for checking shell script syntax errors. It performs static parsing and requires valid UTF-8. To use it for checking without outputting formatted code, redirect stdout to /dev/null.
  11. Convert shell syntax tree to and from JSON

    master

    You can use shfmt to manipulate the shell syntax tree using JSON.

    • Use --to-json to print the syntax tree of the input to stdout as a typed JSON.
    • Use --from-json to read a syntax tree from stdin as a typed JSON and format it.

    Note: These flags can only be used with standard input.