sh


Ⅰ. 插件描述

A shell parser, formatter, and interpreter (sh/bash/mksh) - including shfmt

Ⅱ. 基本信息

创建日期:  2016-01-16
使用用户:  1
Github星:  2532
插件作者:  Daniel Martí

Ⅲ. 安装方法

使用Vundle管理器安装

在你的.vimrc下添加:
Plugin 'mvdan/sh'
… 然后在Vim中运行以下命令:
:source %
:PluginInstall

对于Vundle版本 < 0.10.2,请用上面的Bundle替换Plugin。

使用NeoBundle管理器安装

在你的.vimrc下添加:
NeoBundle 'mvdan/sh'
… 然后在Vim中运行以下命令:
:source %
:NeoBundleInstall

使用VimPlug管理器安装

在你的.vimrc下添加:
Plug 'mvdan/sh'
… 然后在Vim中运行以下命令:
:source %
:PlugInstall

使用Pathogen管理器安装

在终端中运行以下命令:
cd ~/.vim/bundle
git clone https://github.com/mvdan/sh

Ⅳ. 文档说明

# sh

GoDoc
fuzzit

A shell parser, formatter, and interpreter. Supports [POSIX Shell], [Bash], and
[mksh]. Requires Go 1.12 or later.

Quick start

To parse shell scripts, inspect them, and print them out, see the [syntax
examples](https://godoc.org/mvdan.cc/sh/syntax#pkg-examples).

For high-level operations like performing shell expansions on strings, see the
shell examples.

shfmt

GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt

shfmt formats shell programs. It can use tabs or any number of spaces to

  1. See canonical.sh for a quick look at its default
    style.

You can feed it standard input, any number of files or any number of directories
to recurse into. When recursing, it will operate on .sh and .bash files and
ignore files starting with a period. It will also operate on files with no
extension and a shell shebang.

shfmt -l -w script.sh

Typically, CI builds should use the command below, to error if any shell scripts
in a project don't adhere to the format:

shfmt -d .

Use -i N to indent with a number of spaces instead of tabs. There are other
formatting options - see shfmt -h. For example, to get the formatting
appropriate for Google's Style guide, use shfmt -i 2 -ci.

If any [EditorConfig] files are found, they will be used to apply formatting

  1. If any parser or printer flags are given to the tool, no EditorConfig
  2. will be used. A default like -i=0 can be used for this purpose.

An example of the options available:

[*.sh]
# like -i=4
indent_style = space
indent_size = 4

shell_variant      = posix # like -ln=posix
binary_next_line   = true  # like -bn
switch_case_indent = true  # like -ci
space_redirects    = true  # like -sr
keep_padding       = true  # like -kp

# Ignore the entire "third_party" directory.
[third_party/**]
ignore = true

Packages are available on [Alpine], [Arch], [Docker], [FreeBSD], [Homebrew],
[MacPorts], [NixOS], [Scoop], [Snapcraft], and [Void].

Replacing bash -n

bash -n can be useful to check for syntax errors in shell scripts. However,
shfmt >/dev/null can do a better job as it checks for invalid UTF-8 and does
all parsing statically, including checking POSIX Shell validity:

$ echo '${foo:1 2}' | bash -n
$ echo '${foo:1 2}' | shfmt
1:9: not a valid arithmetic operator: 2
$ echo 'foo=(1 2)' | bash --posix -n
$ echo 'foo=(1 2)' | shfmt -p
1:5: arrays are a bash feature

gosh

GO111MODULE=on go get mvdan.cc/sh/v3/cmd/gosh

Proof of concept shell that uses interp. Note that it's not meant to replace a
POSIX shell at the moment, and its options are intentionally minimalistic.

Fuzzing

This project makes use of [go-fuzz] to find crashes and hangs in both the parser
and the printer. To get started, run:

git checkout fuzz
./fuzz

Caveats

  • When indexing Bash associative arrays, always use quotes. The static parser
    will otherwise have to assume that the index is an arithmetic expression.
$ echo '${array[spaced string]}' | shfmt
1:16: not a valid arithmetic operator: string
$ echo '${array[dash-string]}' | shfmt
${array[dash - string]}
  • $(( and (( ambiguity is not supported. Backtracking would complicate the
    parser and make streaming support via io.Reader impossible. The POSIX spec

recommends to space the operands if $( ( is meant.

$ echo '$((foo); (bar))' | shfmt
1:1: reached ) without matching $(( with ))
  • Some builtins like export and let are parsed as keywords. This is to allow
    statically parsing them and building their syntax tree, as opposed to just

keeping the arguments as a slice of arguments.

JavaScript

A subset of the Go packages are available as an npm package called [mvdan-sh].
See the _js directory for more information.

Docker

To build a Docker image, checkout a specific version of the repository and run:

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

This creates an image that only includes shfmt. Alternatively, if you want an
image that includes alpine, add --target alpine.
To use the Docker image, run:

docker run --rm -v $PWD:/mnt -w /mnt my:tag <shfmt arguments>

Related projects

  • Alternative docker images - by jamesmstone, PeterDaveHello
  • [format-shell] - Atom plugin for shfmt
  • [micro] - Editor with a built-in plugin for shfmt
  • [modd] - A developer tool that responds to filesystem changes, using sh
  • [shell-format] - VS Code plugin for shfmt
  • [Sublime-Pretty-Shell] - Sublime Text 3 plugin for shfmt
  • [vim-shfmt] - Vim plugin for shfmt

添加新评论