Static Analysis for Bash and Shell Scripts
If you must write shellcode, use the same techniques you use for your primary programming language and use:
- static analysis
- a standard style guide or format
- a standard library
In fact, given how weird shellcode is, it probably needs these tools even more than your regular languages. Fortunately these tools now exist for shell.
shellcheck provides static analysis of shell scripts and covers an number of different dialects of shell. It's hard to overstate how great this. You'll be horrified at the output and likely learn something as well.
You can use it three ways.
- Online at shellcheck.net. It's a great way to quickly see how screwed-up your scripts actually are.
- Integrated into your editor for real-time checking.
- As CLI for batch testing. Given it's written in Haskell, installation from source might be a bit alien to you. Fortunately most platforms have a binary install.
Protip: You can lint Dockerfiles and the shell script inside them with hadolint.
mvdan/sh and shfmt
shfmt takes your crappy shell code, and makes it beautiful. There is no customization of the format other than "tabs or spaces", but it's a good default format. Use it.
It's a single binary written in go. You can screw around trying to download from GitHub Releases or you can use this downloader script which will do the right thing for your platform.
Disclaimer: I wrote this and the downloader script mentioned above.
The best shell script is one not written. But if you have to use shell, client9/shlib is a collection of tested, portable functions to help you to bootstrap out of shell into something more sane. All the code is in the public domain, so use and remix as needed. Credit and pull requests are welcome but not required.
bashate used by OpenStack to enforce bash style. I think it's mostly superseded by the other tools, but you might like some of it's checks.
BATS is the "Bash Automation Testing System" and provide an xUnit type of testing framework for bash. I think it's overkill but maybe you'll find it useful. If you need something simpler, check out the basic assert functions from client9/shlib.