github.com/teddydd/sh@v2.6.4+incompatible/README.md (about) 1 # sh 2 3 [![GoDoc](https://godoc.org/mvdan.cc/sh?status.svg)](https://godoc.org/mvdan.cc/sh) 4 [![Build](https://travis-ci.org/mvdan/sh.svg?branch=master)](https://travis-ci.org/mvdan/sh) 5 6 A shell parser, formatter and interpreter. Supports [POSIX Shell], [Bash] and 7 [mksh]. Requires Go 1.10 or later. 8 9 **Note**: `v2` is in a feature freeze, and will only receive bugfixes. 10 Development continues on the `mvdan.cc/sh/v3` Go module on the 11 [`master.v3`](https://github.com/mvdan/sh/tree/master.v3) branch. 12 13 ### Quick start 14 15 To parse shell scripts, inspect them, and print them out, see the [syntax 16 examples](https://godoc.org/mvdan.cc/sh/syntax#pkg-examples). 17 18 For high-level operations like performing shell expansions on strings, see the 19 [shell examples](https://godoc.org/mvdan.cc/sh/shell#pkg-examples). 20 21 ### shfmt 22 23 go get -u mvdan.cc/sh/cmd/shfmt 24 25 `shfmt` formats shell programs. It can use tabs or any number of spaces to 26 indent. See [canonical.sh](syntax/canonical.sh) for a quick look at its default 27 style. 28 29 You can feed it standard input, any number of files or any number of directories 30 to recurse into. When recursing, it will operate on `.sh` and `.bash` files and 31 ignore files starting with a period. It will also operate on files with no 32 extension and a shell shebang. 33 34 shfmt -l -w script.sh 35 36 Typically, CI builds should use the command below, to error if any shell scripts 37 in a project don't adhere to the format: 38 39 shfmt -d . 40 41 Use `-i N` to indent with a number of spaces instead of tabs. There are other 42 formatting options - see `shfmt -h`. For example, to get the formatting 43 appropriate for [Google's Style][google-style] guide, use `shfmt -i 2 -ci`. 44 45 Packages are available on [Arch], [CRUX], [Docker], [FreeBSD], [Homebrew], 46 [NixOS], [Scoop], [Snapcraft], and [Void]. 47 48 #### Replacing `bash -n` 49 50 `bash -n` can be useful to check for syntax errors in shell scripts. However, 51 `shfmt >/dev/null` can do a better job as it checks for invalid UTF-8 and does 52 all parsing statically, including checking POSIX Shell validity: 53 54 ```sh 55 $ echo '${foo:1 2}' | bash -n 56 $ echo '${foo:1 2}' | shfmt 57 1:9: not a valid arithmetic operator: 2 58 $ echo 'foo=(1 2)' | bash --posix -n 59 $ echo 'foo=(1 2)' | shfmt -p 60 1:5: arrays are a bash feature 61 ``` 62 63 ### gosh 64 65 go get -u mvdan.cc/sh/cmd/gosh 66 67 Experimental shell that uses `interp`. Work in progress, so don't expect 68 stability just yet. 69 70 ### Fuzzing 71 72 This project makes use of [go-fuzz] to find crashes and hangs in both the parser 73 and the printer. To get started, run: 74 75 git checkout fuzz 76 ./fuzz 77 78 ### Caveats 79 80 * When indexing Bash associative arrays, always use quotes. The static parser 81 will otherwise have to assume that the index is an arithmetic expression. 82 83 ```sh 84 $ echo '${array[spaced string]}' | shfmt 85 1:16: not a valid arithmetic operator: string 86 $ echo '${array[dash-string]}' | shfmt 87 ${array[dash - string]} 88 ``` 89 90 * `$((` and `((` ambiguity is not supported. Backtracking would complicate the 91 parser and make streaming support via `io.Reader` impossible. The POSIX spec 92 recommends to [space the operands][posix-ambiguity] if `$( (` is meant. 93 94 ```sh 95 $ echo '$((foo); (bar))' | shfmt 96 1:1: reached ) without matching $(( with )) 97 ``` 98 99 * Some builtins like `export` and `let` are parsed as keywords. This is to allow 100 statically parsing them and building their syntax tree, as opposed to just 101 keeping the arguments as a slice of arguments. 102 103 ### JavaScript 104 105 A subset of the Go packages are available as an npm package called [mvdan-sh]. 106 See the [_js](_js) directory for more information. 107 108 ### Docker 109 110 To build a Docker image, checkout a specific version of the repository and run: 111 112 docker build -t my:tag -f cmd/shfmt/Dockerfile . 113 114 ### Related projects 115 116 * Alternative docker images - by [jamesmstone][dockerized-jamesmstone], [PeterDaveHello][dockerized-peterdavehello] 117 * [format-shell] - Atom plugin for `shfmt` 118 * [micro] - Editor with a built-in plugin for `shfmt` 119 * [shell-format] - VS Code plugin for `shfmt` 120 * [vim-shfmt] - Vim plugin for `shfmt` 121 122 [arch]: https://www.archlinux.org/packages/community/x86_64/shfmt/ 123 [bash]: https://www.gnu.org/software/bash/ 124 [crux]: https://github.com/6c37/crux-ports-git/tree/HEAD/shfmt 125 [docker]: https://hub.docker.com/r/mvdan/shfmt/ 126 [dockerized-jamesmstone]: https://hub.docker.com/r/jamesmstone/shfmt/ 127 [dockerized-peterdavehello]: https://github.com/PeterDaveHello/dockerized-shfmt/ 128 [examples]: https://godoc.org/mvdan.cc/sh/syntax#pkg-examples 129 [format-shell]: https://atom.io/packages/format-shell 130 [freebsd]: https://github.com/freebsd/freebsd-ports/tree/HEAD/devel/shfmt 131 [go-fuzz]: https://github.com/dvyukov/go-fuzz 132 [google-style]: https://google.github.io/styleguide/shell.xml 133 [homebrew]: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/shfmt.rb 134 [micro]: https://micro-editor.github.io/ 135 [mksh]: https://www.mirbsd.org/mksh.htm 136 [mvdan-sh]: https://www.npmjs.com/package/mvdan-sh 137 [nixos]: https://github.com/NixOS/nixpkgs/blob/HEAD/pkgs/tools/text/shfmt/default.nix 138 [posix shell]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html 139 [posix-ambiguity]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03 140 [shell-format]: https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format 141 [scoop]: https://github.com/lukesampson/scoop/blob/HEAD/bucket/shfmt.json 142 [snapcraft]: https://snapcraft.io/shfmt 143 [vim-shfmt]: https://github.com/z0mbix/vim-shfmt 144 [void]: https://github.com/voidlinux/void-packages/blob/HEAD/srcpkgs/shfmt/template